Gitlab+docker 代码自动化部署

1,804 阅读7分钟

Gitlab+docker 代码自动化部署

本文涉及到的一些小知识

  • docker
  • gitlab
  • gitlab-runner
  • 一点点的linux
  • 一点点的nginx
  • 或者还需要一点docker-compose
  • 这样的部署方式适用于前后端,不限于本文涉及的部署项目。
  • 本文内容比较干,建议使用GPT结合食用

多看一眼就会爆炸,再靠近一点就会被融化

披金成王

每次部署都很繁琐

由于我自己采用的部署方式是docker镜像,每次都需要重新构建docker镜像,这一步往往都是手动操作

之前的构建方式

  • 推送代码到gitlab
  • 进入服务器
  • 拉取最新代码
  • 安装依赖
  • 构建项目
  • 根据当前项目的Dockerfile构建docker镜像
  • 利用docker-compose执行项目的Dcokerfile文件
  • 需要先使用docker-compose up 执行项目,看看是否有报错,有报错的话先溯源
  • 如果没有报错,使用docker-compose up -d 后台运行项目。
  • 需要查看对应项目的logs,利用docker ps -a 找到你项目的id,并使用docker logs -f xxxxid
  • docker 根据文件名查询容器 docker ps -q -f name=container-name

更新之后的部署方式

!!!! 推送代码,结束了~

所有流程都让流水线来帮你完成~

so,how to do it?

前置工作必须得做好哦,本文涉及到较多docker-compose创建应用,可以先了解一下哦~

Docker Compose | 菜鸟教程 (runoob.com)

你需要有一个代码管理工具(Gitlab)

建议直接用docker-compose创建,很方便。不需要后期修改容器内部的配置文件。

version: '2'
services:
    gitlab:
      image: 'twang2218/gitlab-ce-zh:11.1.4'
      container_name: "gitlab"
      restart: unless-stopped
      privileged: true
      hostname: 'gitlab'
      environment:
        TZ: 'Asia/Shanghai'
        GITLAB_OMNIBUS_CONFIG: |
          external_url 'http://www.lvzy.xyz:9527'
          gitlab_rails['gitlab_ssh_host'] = 'http://www.lvzy.xyz'
          gitlab_rails['gitlab_shell_ssh_port'] = xxxx
          gitlab_rails['time_zone'] = 'Asia/Shanghai'
          gitlab_rails['smtp_enable'] = true
          gitlab_rails['smtp_address'] = "smtp.qq.com"
          gitlab_rails['smtp_port'] = 465
          gitlab_rails['smtp_user_name'] = "xxxxxxxx@qq.com"
          gitlab_rails['smtp_password'] = "xxxxxxx"
          gitlab_rails['smtp_domain'] = "qq.com"
          gitlab_rails['smtp_authentication'] = "login"
          gitlab_rails['smtp_enable_starttls_auto'] = true
          gitlab_rails['smtp_tls'] = true
          gitlab_rails['gitlab_email_from'] = 'gitlab邮件提醒'
          gitlab_rails['gitlab_shell_ssh_port'] = 22
          gitlab_rails['gitlab_replay_to'] = "xxxxxxx@qq.com"
      # 端口映射,容器内部的端口映射到宿主机。比如项目启动起来,容器内部访问为localhost:9527,映射就是->服务器ip:9527
      ports:
        - '9527:9527'
        - '9430:443'
        - '9922:22'
      volumes:
        # 映射文件夹,就算删除容器,你自己的项目还是会在。重新建立依然可以保留~
        - /var/apps/gitlab/config:/etc/gitlab
        - /var/apps/gitlab/data:/var/opt/gitlab
        - /var/apps/gitlab/logs:/var/log/gitlab
        #所以,此处的/vra/apps/gitlab/xxx路径,其实是你宿主机的路径,项目运行生成的文件也会在宿主机中得到持久化。创建的时候你也的得创建对应的目录出来

image.png

完成以上步骤之后,你需要访问你的gitlab,设置初始密码~

登录 · GitLab (lvzy.xyz)

image.png

创建一个属于demo项目,作为测试构建的应用

我这里使用的是一个vue3+vite的项目

项目地址

image.png

创建gitlab runner

我大部分创建容器都是利用docker-compose创建,也可以改造为docker命令自行创建~以下是一个基础gitlab runner构建的yml文件。当然,在此之前你还需要创建一个/config/config.toml 的文件路径,来保证runner的正确启动。

version: '3'
services:
  gitlab-runner:
    image: gitlab/gitlab-runner:latest
    container_name: gitlab-runner
    restart: always
    volumes:
      # 这两步骤是为了让容器内的gitlab-runner可以访问到docker
      - /var/run/docker.sock:/var/run/docker.sock
      - /bin/docker:/bin/dcoker
      # 将当前目录的config文件,映射到容器的/etc/gitlab-runner目录
      - ./config:/etc/gitlab-runner
    environment:
      # 也是指定docker
      RUNNER_EXECUTOR: "docker"

config.toml文件的内容

concurrent = 1
check_interval = 0

[session_server]
  session_timeout = 1800

当你以上工作都已经完成之后,就可以正式开始了

docker ps -q -f name="gitlab-runner"
# 237fc2c3a09a
# 先看看gitlab-runner是否跑起来了,输出正确的容器id 就是跑起来了

此时需要你先准备一个东西,gitlab的token,具体位置是到你的项目下,找到设置,设置中的cicd,选择runner,会有一个token

image.png

image.png

红框部分需要记住~

#开始把runner,链接到gitlab
docker exec -it gitlab-runner gitlab-runner register \
  --non-interactive \
  --url "https://gitlab.example.com" \
  --registration-token "TOKEN" \
  --executor "docker" \
  --description "My Docker Runner" \
  --docker-image "docker:19.03.12" \
  --tag-list "docker,linux,xenial" \
  --run-untagged="true" \
  --locked="false" \
  --access-level="not_protected"
#   --url:指定你的 GitLab 服务器地址。
#   --registration-token:刚刚获取的 GitLab Runner 注册 Token。
#   --executor:指定 GitLab Runner 服务器的执行器,这里指定为 Docker。
#   --description:Runner 的描述信息,可以自定义。
#   --docker-image:指定容器运行时使用的 Docker 镜像版本。
#   --tag-list:为 Runner 打标签,例如 "docker"、 "linux" 和 "xenial"。
#   --run-untagged:允许

# 笔者是直接使用 docker exec -it gitlab-runner gitlab-runner register,每一步跟着敲的,没使用一键命令。

完成以上操作后,去查看runner的配置文件。是否有你注册的runner,并且还需要查看logs,看看是否报错,如果有报错,仔细检查,并重新操作。这个是我已经配置完成后的log,大概这样子.

image.png

如果没有报错,那么进入你的项目,查看runner,如果成功了,会有一条记录,并且是active状态。

image.png

到这一步,基本完成了大部分了

拉取你的项目,做一些项目里的配置~

Dockerfile是必须的

Dockerfile是用来给你的项目打包镜像使用,在执行镜像的时候具体要做些什么。

# 设置 Node.js 版本
FROM node:16.14-alpine3.14 AS builder

# 安装 pnpm
RUN npm install -g pnpm
# 创建应用程序目录并将其设为工作目录
WORKDIR /app

# 将 package.json 和 package-lock.json(或 yarn.lock)复制到应用程序目录
COPY package*.json ./
# 安装应用程序依赖
RUN pnpm install

# 将应用程序的所有文件复制到应用程序目录

COPY . .

# 构建应用程序
RUN pnpm run build

FROM nginx:latest

COPY --from=builder /app/dist /opt/www

# RUN rm /etc/nginx/conf.d/default.conf

COPY --from=builder /app/nginx.conf /etc/nginx/nginx.conf

CMD ["nginx","-g","daemon off;"]

nginx.conf,用来处理请求访问

这个配置只会在你生成的项目镜像内生效,不会影响其他项目


http {
  include /etc/nginx/mime.types;
  default_type application/octet-stream;
  server {
    listen 80;
    charset utf-8;
    root /opt/www;

    location / {
      # 此处的 @router 实际上是引用下面的转发,否则在 Vue 路由刷新时可能会抛出 404
      try_files $uri $uri/ @router;
      # 请求指向的首页
      index index.html;
    }
    # 由于路由的资源不一定是真实的路径,无法找到具体文件
    # 所以需要将请求重写到 index.html 中,然后交给真正的 Vue 路由处理请求资源
    location @router {
      rewrite ^.*$ /index.html last;
    }
    error_page 500 502 503 404 /404.html;
    location = /404.html {
        root /usr/share/nginx/html;
    }
  }
}
events {
      # 配置 Nginx 工作进程的最大数量
    worker_connections 1024;

    # 配置 Nginx 所使用的事件驱动模块
    use epoll;
}

有些同学可能要问,为什么要配置events,是因为我这边用的nginx镜像,自带的没有配置他。需要手动配置一番。此处还应注意HTTP下的includedefault_type,如果不配置,返回的静态文件的content-type可能会有问题,需要指定一下

.gitlb-ci.yml,让你的流水线和当前项目挂钩~

.gitlab-ci.yml是必要的文件,push代码时,会检测是否包含此文件,如果不包含,不会执行流水线的哦~

# stages,将流水线分为两步,第一步执行打包镜像的命令--build
# 第二步,执行启动镜像的命令 ---deploy
stages:
  - "build"
  - "deploy"
services:
  - docker:dind
build:
  stage: build
  tags:
    - build
  script:
     # 两个if,用来处理之前的数据
     # 判断当前项目是否正在运行,如果正在运行,则停止,并删除这个容器,防止端口占用,导致deploy启动失败
    - if [ $(docker ps -q -f name=runner-project) ]; then docker stop runner-project && docker rm runner-project; fi
    # 由于我服务器内存较小,在构建新的镜像之前,我会删除掉之前的旧镜像。
    - if docker images | awk '{print $1"_"$2}' | grep -qx runner-project; then docker rmi runner-project; fi
    # 执行build,这一步跟之前的Dockerfile挂钩,其实执行的就是Dockerfile里的命令
    - docker build -t runner-project .
deploy:
  stage: deploy
  tags:
    - build
  script:
    - docker run -d -p 10880:80 runner-project #启动


# 如果你需要指定分支打包,可以使用only字段,限定分支打包,支持正则匹配哦

ok,看看效果

推送代码

推送代码的时候,会自动触发流水线,直接进入项目查看。

image.png

点进去查看一下具体内容,可以看到有两个过程,这个就是我们在.gitlab-ci.yml里面写的过程。点击具体step,可以查看更多详情。

image.png

image.png

查看服务器容器是否启动

image.png

这里可以看到,容器已经正常启动起来了~

访问项目

image.png

ok,没有任何问题!

是否可以用于公司部署项目?

No!

这是个玩具,不能用于公司部署

这个前一部分是可以用于公司的,没有任何问题~问题在哪呢,问题出在直接部署上面。 公司部署项目,是有多个环境的。而且也不是说上传代码立马部署。需要指定时间。 那么,就需要构造一个发布中心。原有的镜像,也不需要删除,留着就是,指定服务器发布指定的镜像。 具体的操作还是比较繁琐,所以我说这个就是个玩具。

每一个新项目都需要一个新的端口号支撑?

这个类似于一个服务,肯定会涉及到端口占用的问题。

如何优化?

在宿主机安装一个nginx,做路径转发。比如项目A,访问是localhost:10088,在宿主机中 /proecjt-a/-> rewrite localhost:10088,也是很不错的一个思路。

at last,想找份工作。

挺惨的哈哈哈,失业了。

希望在重庆、成都、北上广。

**[有路子的ikun,加我一起学习](url)**