Gitlab CI/CD 部署前端与Golang后端至Nginx服务器

8,043 阅读3分钟

Gitlab

阅读该链接获取详细的gitlab与gitlab-runner安装 Docker 安装与配置 Gitlab

安装Gitlab

mkdir -p /data/gitlab/config
mkdir -p /data/gitlab/logs
mkdir -p /data/gitlab/data

docker run -d \
-h <host> \
-p 443:443 -p <port>:80 -p 2222:22 \
-e TZ=Asia/Shanghai \
--shm-size 256m \
--name gitlab \
--restart always \
-v /data/gitlab/config:/etc/gitlab \
-v /data/gitlab/logs:/var/log/gitlab \
-v /data/gitlab/data:/var/opt/gitlab \
gitlab/gitlab-ce:latest

Gitlab-Runner

gitlab需要runner, 安装

mkdir -p /data/gitlab-runner5/config

docker run \
-d \
--name gitlab-runner \
--restart always \
-v /data/gitlab-runner/config:/etc/gitlab-runner \
-v /var/run/docker.sock:/var/run/docker.sock \
gitlab/gitlab-runner:latest

注册Gitlab-Runner

注册一个或多个gitlab-runner对项目进行流水线作业

docker run \
-it \
-v /data/gitlab-runner/config:/etc/gitlab-runner \
gitlab/gitlab-runner:latest register

部署

前端

Cache

key:

  1. 缓存node_modules,下一次的流水线无需全部安装一次(可优化点)
  2. 保留build打包之后的dist目录,给下一个Job使用
init Job部分

script脚本解释:

  1. 使用node:14-alpine容器对前端项目进行安装
  2. (可选)项目使用pnpm包管理器, 所以全局安装pnpm使用
  3. 打包项目
deploy Job部分
  • image: rockylinux: Ceontos的替代发行版

  • script脚本解释:

  1. 生成索引缓存索引提供搜索安装速度
  2. 下载sshpass,openssh-clients用于SSH登录服务器
  3. 进入打包后的dist目录,对里面所有文件进行压缩,并排除node_modules,压缩后名文件为dist.tar.gz
  4. 设置生产服务器的密码的变量为SSHPASS,从gitlab的环境变量获取
  5. 发送dist.tar.gz文件至生产服务器的nginx路径
  6. 进入到生产服务器的nginx路径, 对dist.tar.gz文件进行解压, 解压完成后删除dist.tar.gz文件
stages:
  - init
  - deploy

cache:
  key: frond-end
  paths:
    - node_modules
    - dist

job_init:
  stage: init
  image: node:14-alpine
  tags:
    - cd2
  script:
    - npm install pnpm -g
    - pnpm install
    - pnpm build
  only:
    - main
  artifacts:
    paths:
      - build/

job_deploy:
  stage: deploy
  image: rockylinux
  only:
    - main
  tags:
    - cd2
  script:
    - yum makecache
    - yum install -y sshpass  openssh-clients
    - cd dist && tar -czvf dist.tar.gz --exclude=node_modules ./*
    - export SSHPASS="$PASSWORD"
    - sshpass -e scp -o stricthostkeychecking=no ./dist.tar.gz root@'192.168.0.158':/home/nginx/html/web/
    - sshpass -e ssh -o stricthostkeychecking=no root@192.168.0.158 'tar -xzvf /home/nginx/html/web/dist.tar.gz -C /home/nginx/html/web && rm -rf /home/nginx/html/web/dist.tar.gz'

Golang

stages:
  - build
  - deploy

# 设置缓存,设置需要保存的产物 下一个Job不会保存前一个Job的资源
cache:
  key: go-build # 如果设置多个Key, 有相同的key会覆盖
  paths:
    - app # 需要保存的产物

# 打包Golang项目为二进制文件
job_build:
  stage: build
  image: golang # 利用Golang容器进行打包Golang项目
  tags:
    - golang
  script:
    - go env -w GOPROXY=https://goproxy.cn,direct
    - go get
    - go build -o app
    - chmod +x app

job_deploy:
  stage: deploy
  image: rockylinux
  only:
    - main
  tags:
    - golang
  script:
    - yum makecache # 生成索引缓存索引提供搜索安装速度
    - yum install -y sshpass  openssh-clients
    - export SSHPASS="$PASSWORD" # 密码,从gitlab的环境变量设置与获取
    - sshpass -e scp -o stricthostkeychecking=no ./dir.sh root@192.168.0.158:/ # sshpass -e 从环境变量获取密码 scp -o stricthostkeychecking=no 忽略RSA Key检查信息
    - sshpass -e ssh -o stricthostkeychecking=no root@'192.168.0.158' 'cd / && bash dir.sh && rm -rf dir.sh'
    - sshpass -e scp -o stricthostkeychecking=no ./app ./Dockerfile ./deploy.sh root@192.168.0.158:/home/temp # sshpass -e 从环境变量获取密码 scp -o stricthostkeychecking=no 忽略RSA Key检查信息
    - sshpass -e ssh -o stricthostkeychecking=no root@'192.168.0.158' 'cd /home/temp && bash deploy.sh' #执行 sh

dir.sh 创建临时目录

#!/bin/bash

# 需要创建的目录
dir=/home/temp
# 列出该目录所有文件
res=$(ls -A $dir)
# 检查该目录是否有文件, 没有则创建
if [ -z "$res" ]; then
  mkdir -p /home/temp
fi

deploy.sh

#!/bin/bash

# 检测goimage(.gitlab-ci.yml提供的golang打包后的二进制文件的名称)是否已在运行, 如果已在运行则停止该容器
# docker ps 列出Docker容器列表
# grep goimage 搜索docker ps 列出Docker容器列表有没有goimage这个字串
# awk '{print $12}' 从docker ps 列出Docker容器列表的第12列(容器名)
# docker stop goimage 停止运行goimage容器
if [ $(docker ps | grep goimage | awk '{print $12}') ]; then docker stop goimage; fi

# 如果goimage容器存在 则删除该容器
# docker ps -a 列出全部容器
# docker ps -q 静默模式,只列出容器编号
# docker ps -aq 列出全部容器编号
# --filter name=goimage 过滤出容器名称为goimage的容器
# docker rm -f goimage 删除goimage容器
if [ $(docker ps -aq --filter name=goimage) ]; then
  docker rm -f goimage
fi

# docker images 列出所有镜像
# docker rmi -f 强制删除
# docker rmi -f goimage 强制删除goimage镜像
if [ $(docker images | grep goimage | awk '{print $1}') ]; then docker rmi -f goimage; fi

# 在本目录打包一个镜像名字及标签为goimage的二进制文件可运行的Docker镜像
# docker build --tag 镜像的名字及标签,通常 name:tag 或者 name 格式;可以在一次构建中为一个镜像设置多个标签。
docker build --tag goimage .

# docker run 运行
# -d 后台运行容器,并返回容器ID
# -p 映射主机与容器的端口
# --name 容器名称
docker run -d -p 4000:4000 --name goimage goimage

# 删除上传的文件
rm -rf /home/temp