golang+react使用gitlab-runner自动打包并发布docker镜像

0x00 环境配置

  1. gitlab-serverA:安装了gitlab-ce的debian操作系统(本文发布时使用 gitlab-ce v17.6.0版本),如何安装gitlab建议参考官方文档或清华大学开源软件镜像站使用帮助

  2. dev-server:安装了docker的debian操作系统,如何安装docker建议参考官方文档或清华大学开源软件镜像站使用帮助

注意:本文涉及到的runner、golang打包、前端打包等操作全采用docker compose方式运行,涉及带版本号的软件包/环境,均使用latest/stable镜像,请根据实际情况选择版本。

本文设计涉及到的域名如下:

  • https://register.example.com 用于docker私有镜像的访问,您也可以根据您的实际需求选择ip地址直接访问

0x01 gitlab-runner注册及docker仓库的安装

gitlab-runner及docker私有仓库的compose模板配置

  1. 首先,贴出docker-compose.yml模板文件,是否需要registry请自行取舍,这里仅为演示所用。

services:
  gitlab-runner:
    image: gitlab/gitlab-runner:latest
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./runner/config:/etc/gitlab-runner
    restart: on-failure
  docker-registry:
    image: registry:latest
    volumes:
      - ./registry_data/registry:/var/lib/registry
      - ./registry_data/auth:/auth
    ports:
      - "5000:5000"
    environment:
      - REGISTRY_AUTH=htpasswd
      - REGISTRY_AUTH_HTPASSWD_REALM="Resistry Realm"
      - REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd
  1. 由于认证使用了htpasswd,首先需要安装软件包apache2-utils:


apt install apache2-utils
  1. 将htpasswd认证账号密码写入docker-compose.yml文件路径下的registry_data/auth/auth/htpasswd文件内

  2. 运行容器

docker compose up -d

gitlab的CICD环境变量设置及runner设置(docker in docker方式)

tips:环境变量仅针对单个项目设置,您也可以自行选择配置全局变量

  1. 打开gitlab,进入某个项目,在左侧菜单栏进入设置-CI/CD 菜单,在变量选型中为其添加以下字段变量

  • Key:DOCKER_PASSWORD,Value:私有仓库账号

  • Key:DOCKER_USERNAME,Value:私有仓库密码

  1. Runner 中新建一个项目runner。注意:如您准备采用本文的ci配置,您在建立的时候需要勾选运行未打标签的作业,本文不涉及到标签操作,您需要自行去配置。

  2. 点击创建Runner后,会展示Runner身份验证令牌,请在docker容器内手动执行命令注册Runner,注意:请自行修改url地址及token。因为涉及到容器内通信,这里解释一下,因为要启动其他容器,所以说使用了 privileged mode,runner也并不一定是已docker方式,gitlab给出了详细的文档,本文仍然采用docker方式运行。

# 进入容器
docker compose exec -it gitlab-runner /bin/bash
# 容器内注册命令
gitlab-runner register -n \
--executor docker \
--docker-image "docker:latest" \
--docker-privileged \
--url <gitlab server 地址> \
--token <runner token>
  1. 因为涉及容器间通信,且runner也采用docker安装,想必你也不愿意看到类似Is the docker daemon running? 的错误吧?那咱们就一切从简,修改一下runner的配置文件

  • runner/config/config.toml 中增加卷映射将其修改为volumes = ["/var/run/docker.sock:/var/run/docker.sock","/cache"]

0x02 ci文件编写

.gitlab-ci.yml

  1. 首先因为需要clone代码,您需要创建一个访问令牌(左侧菜单栏-设置-访问令牌),可以按群组/项目设置,按实际需求设置即可,权限部分只需要勾选read_repository 即可。以下所有配置文件中涉及到的镜像、命名、用户名、Token、服务器网址等请按实际修改。

stages:
  - clone_frontend
  - clone_backend
  - docker_build

variables:
  DOCKER_IMAGE: "registry.exmple.com/test"
  DOCKER_TAG: "latest"


clone_frontend:
  stage: clone_frontend
  script:
    - echo "Cloning frontend project..."
    - git clone https://<YOUR_USERNAME>:<YOUR_TOKEN>@git.example.com/test/test_frontend.git frontend
  artifacts:
    paths:
      - frontend/

clone_backend:
  stage: clone_backend
  script:
    - echo "Cloning backend project..."
    - git clone http://<YOUR_USERNAME>:<YOUR_TOKEN>@git.example.com/test/test_backend backend 
  artifacts:
    paths:
      - backend/

docker_build:
  stage: docker_build
  image: docker:stable
  services:
  - name: docker:dind
    alias: docker
    command: ["--tls=false"]
  variables:
    DOCKER_TLS_CERTDIR: ""
    DOCKER_HOST: tcp://localhost:2375
    DOCKER_DRIVER: overlay2
  before_script:
    - echo "Setting up Docker..."
    - echo "$DOCKER_PASSWORD" | docker login https://registry.example.com --username "$DOCKER_USERNAME" --password-stdin
  script:
    - unset DOCKER_HOST
    - echo "Building Docker image..."
    - docker build -t $DOCKER_IMAGE:$DOCKER_TAG .
    - echo "Pushing Docker image to private registry..."
    - docker push $DOCKER_IMAGE:$DOCKER_TAG

Dockerfile

FROM node:20 AS frontend
WORKDIR /app/frontend
COPY frontend ./
RUN yarn config set strict-ssl false \
    && yarn config set registry https://registry.npmmirror.com/
RUN yarn install
RUN yarn build
RUN rm ./build/static/css/*.map \
    && rm ./build/static/js/*.map

FROM golang:latest AS backend
WORKDIR /app/backend
ENV GOPROXY=https://goproxy.io,direct
ENV GOOS=linux
ENV GOARCH=amd64
COPY backend/go.mod backend/go.sum ./
RUN go mod download
COPY backend ./
RUN go build -o main_app_latest

FROM alpine:latest
WORKDIR /app
COPY --from=frontend /app/frontend/build ./statics
COPY --from=backend /app/backend/main_app_latest ./main_app_latest
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories
RUN apk update \
    && apk add --no-cache tzdata libc6-compat \
    && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && echo "Asia/Shanghai" > /etc/timezone
RUN chmod +x ./main_app_latest
ENTRYPOINT ["./main_app_latest"]

0x03 实际测试

  1. git push之后会自动按配置的流水线进行打包,当您看到流水线作业如下图所示的时候,您的镜像已经上传成功了

0x04 后记

Comment