从头开始配置Gitlab的CI/CD实现Vue项目自动部署
简述
CI/CD早不是什么新鲜玩意儿了,在公司时有专职运维,给我们配置好了自动化构建和部署。特别是自动化部署,很是方便,但是自己私下的项目也想使用,今天就实践了一下,并把遇到的一些坑记录下来。
Gitlab是一款常用的代码自托管系统,在过去经历的公司中大多采用它。它功能强大易用,但是需要较多系统资源,特别是内存,最好8G以上,本次测试使用的是我本地一台64G内存的Nas。
本次以Vue3项目为例,一步一步实现提交代码到Gitlab之后,自动使用最新代码部署。
原理
原理其实很简单,我们在系统中配置好runner,代码提交后读取项目中的.gitlab-ci.yml
文件,根据配置进行构建,并执行部署命令
Gitlab配置
Gitlab和Runner的安装
如今安装软件我一般都使用docker-compose,写好配置文件,可以反复使用,一键安装。
version: "2"
services:
gitlab:
image: 'docker.nju.edu.cn/gitlab/gitlab-ce'
container_name: gitlab1
restart: unless-stopped
hostname: 'gitlab'
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'https://gitlab.air.nload.top/'
gitlab_rails['gitlab_shell_ssh_port'] = 12222
nginx['listen_port'] = 5000
nginx['listen_https'] = false
nginx['redirect_http_to_https'] = false
ports:
- '5000:5000'
- '12222:22'
volumes:
- '/data/gitlab/config:/etc/gitlab'
- '/data/gitlab/logs:/var/log/gitlab'
- '/data/gitlab/data:/var/opt/gitlab'
gitlab-runner:
image: 'docker.nju.edu.cn/gitlab/gitlab-runner'
container_name: gitlab-runner1
restart: unless-stopped
environment:
GITLAB_URL: 'https://gitlab.air.nload.top/'
GITLAB_RUNNER_TOKEN: 'glrt-pnnDPdFoM2121X1YxxsB'
GITLAB_RUNNER_EXECUTOR: 'docker'
GITLAB_RUNNER_DOCKER_IMAGE: 'docker:latest'
GITLAB_RUNNER_DOCKER_PRIVILEGED: 'true'
GITLAB_RUNNER_DOCKER_VOLUMES: '/var/run/docker.sock:/var/run/docker.sock'
volumes:
- '/data/gitlab/runner/config:/etc/gitlab-runner'
- '/var/run/docker.sock:/var/run/docker.sock'
配置文件比较简单,由于墙的原因,国内使用Docker经常遇到网络问题,这里我使用了南京大学的Docker镜像,直接在image名称前加上域名即可。
Gitlab的web我使用了5000端口,前端使用Caddy进行反代和https加密。ssh使用了非22端口,避免和系统冲突。
gitlab-runner相关的配置也可以不写,等系统部署好用另外的方式填上。
然后运行docker-compose up -d
,Gitlab启动较慢,稍等片刻就可以在浏览器中打开你配置的网址了。
创建Runner
打开https://gitlab.air.nload.top/admin/runners
这个页面,新建一个Runner,其实没有太多要填的内容,只填一个tags即可,和项目中保持一致即可
创建完毕会出现一行命令,用于Runner的注册,要记下来,因为只会显示一次,我的是
gitlab-runner register --url https://gitlab.air.nload.top --token glrt-vxARG_k1jHYqvbyRT4RQ
Runner配置
在第一步,我们的runner已经运行起来了,如果你没有更改容器名称,可以用这个命令进入容器的shell
docker exec -it gitlab-runner1 bash
然后运行上一步得到的命令,会有些提示,让你输入内容,基本默认值就行,image随便填就行,我们在项目里再定义。
如果没有什么意外的话,就注册成功了,也可以在网页管理界面中看到runner的状态。
如果失败了,可能是url问题,确保容器里可以访问到这个url。
成功执行以后,我们打开生成的配置文件编辑一下,这里我是在宿主机编辑的vi /data/gitlab/runner/config/config.toml
concurrent = 1
check_interval = 0
shutdown_timeout = 0
[session_server]
session_timeout = 1800
[[runners]]
name = "b902dbedf3ab"
url = "https://gitlab.air.nload.top"
id = 1
token = "glrt-pnnDPdFoM2121X1YxxsB"
token_obtained_at = 2023-12-07T15:02:49Z
token_expires_at = 0001-01-01T00:00:00Z
executor = "docker"
[runners.cache]
MaxUploadedArchiveSize = 0
[runners.docker]
tls_verify = false
image = "docker.nju.edu.cn/docker:24.0.7"
privileged = true
disable_entrypoint_overwrite = false
oom_kill_disable = false
disable_cache = false
volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
shm_size = 0
network_mtu = 0
注意有几处修改,privileged = true
,volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
特别是volume,刚开始配置好一直报错ERROR: error during connect: Get "http://docker:2375/_ping": dial tcp: lookup docker on 223.5.5.5:53: no such host
,修改volume之后就好了。修改完后要重启runner,docker restart gitlab-runner1
项目配置
在Docker中把项目跑起来
我今天配置的是Vue项目,其他语言也差不多,换一下镜像和命令即可。首先是Dockerfile
,一个很常规的docker配置文件,第一步使用nodejs构建,然后把打包后的文件复制到nginx容器中并运行nginx,为了方便,我把nginx.conf配置文件也贴出来吧。
# build stage
FROM docker.nju.edu.cn/node:lts as build-stage
WORKDIR /app
COPY . .
RUN yarn && yarn build
# production stage
FROM docker.nju.edu.cn/nginx:stable as production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
server {
listen 80;
listen [::]:80;
server_name _;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location /assets/ {
access_log off;
add_header Cache-Control public;
expires max;
alias /usr/share/nginx/html/assets/;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
有了上边两个文件,就可以在Docker中运行项目了,
.gitlab-ci.yml 文件
在项目根目录,创建一个.gitlab-ci.yml
文件,内容如下
variables:
IMAGE: ${CI_PROJECT_NAME}:${CI_PROJECT_NAMESPACE}-${CI_COMMIT_BRANCH}-${CI_COMMIT_SHORT_SHA}
stages:
- build
- deploy
build-image:
stage: build
image: docker.nju.edu.cn/docker:24
script:
- docker build -t ${IMAGE} .
tags:
- runner
deploy-to-server:
stage: deploy
when: on_success
needs:
- build-image
script:
- docker stop info-center-web1 && docker rm info-center-web1
- docker run -d --name info-center-web1 -p 1895:80 ${IMAGE}
tags:
- runner
解释一下,首先是一些变量定义,用于镜像的tag。
构建分两个阶段,build和deploy,也有其他的可用,test之类的需要可以看文档。
build阶段就是简单的构建镜像用于运行,deploy阶段则是部署,我这里先把旧容器删掉,又启动了新容器,你可以根据实际情况修改,总之就是你手动运行Docker时怎么写,这里就怎么写。配置好提交到服务器应该就会触发自动部署了。可以在项目的CI/CD的pipelines里查看状态。如果你想自动构建,手动部署,就把yaml文件的when修改成manual
,如果想只部署特定分支,也可以指明。gitlab提供了超多的功能选项,我这里知识抛砖引玉,有需要可以查看文档 https://docs.gitlab.com/ee/topics/build_your_application.html