CI/CD - Docker + GitLab 本地搭建私服 (1)

介绍

CI/CD 即 Continuous IntegrationContinuous Deployment 的缩写,是一种软件开发流程,旨在通过自动化的工具交付,使软件的构建、测试和发布更加的高效、稳定。

通常步骤包含如下:

  • 代码提交到版本托管平台,触发自动化构建和测试钩子
  • 执行任务后,自动部署到生产环境

流程涉及到的环境和工具:

  • 环境:本地 localhost。
  • Docker: 版本 24.0.5
  • GitLab CE: 基于 Git 实现的代码仓库管理系统平台,类似于 GitHub,但有更加强大的管理、权限功能,适合公司搭建内部的代码托管。(版本 16.4.1)
  • GitLab-Runner :GitLab CI 是 GitLab 内置的持续集成工具,在仓库根目录下创建 .gitlab-ci.yml 文件,并配置 GitLab Runner ,每次提交代码时 Runner 将执行 CI/CD pipeline 流程。(版本 16.4.1)

思路

  • Docker 本地启动 GitLab,GitLab-Runner 两个容器
  • 在 GitLab 创建一个项目,在项目根目录里创建 .gitlab-ci.yml 文件,用于定义 CI/CD pipeline 流程
  • 在 GitLab-Runner 注册一个 Runner,关联项目
  • 将代码推送到 GitLab,触发 GiLab-Runner 执行 .gitlab-ci.yml 内的若干指令:构建、部署等

Docker 的内存和 CPU 最好配高点,避免出现一些不好定位的问题(推荐 2 核 + 6 GB)

部署 GitLab

步骤

  1. 挂载配置、日志和数据信息,避免容器删除后数据全部丢失。先创建一个环境变量执指向 GitLab 目录
bash 复制代码
export GITLAB_HOME=$HOME/gitlab
  1. 运行 GitLab 镜像
bash 复制代码
sudo docker run --detach \
  --hostname localhost \
  --publish 443:443 --publish 80:80 --publish 22:22 \
  --name gitlab \
  --restart always \
  --volume $GITLAB_HOME/config:/etc/gitlab \
  --volume $GITLAB_HOME/logs:/var/log/gitlab \
  --volume $GITLAB_HOME/data:/var/opt/gitlab \
  --shm-size 256m \
  gitlab/gitlab-ce:latest

GitLab 本身镜像大及启动的服务较多,整个过程时间长到 3~5min,使用 docker ps 查看容器是否为由 starting 变成 healthy 状态,即启动完成

常见命令

bash 复制代码
gitlab-ctl start/stop/restart 启动/停止/重启 gitlab 所有组件
gitlab-ctl status 查看服务状态
gitlab-ctl reconfigure 重启服务
gitlab-ctl tail 查看日志
  1. 登录

在 localhost 登录 GitLab,用户名默认为 root, 密码使用命令获取 sudo docker exec -it gitlab grep 'Password:' /etc/gitlab/initial_root_password,注意密码将在容器启动后 24 小时删除

部署 GitLab-Runner

步骤

  1. 启动 GitLab-Runner 容器
bash 复制代码
docker run -d --name gitlab-runner \
  --restart always \
  -v /var/run/docker.sock:/var/run/docker.sock \
  gitlab/gitlab-runner:latest
  1. 注册 Runner

在 GitLab 项目的 Settings => CI/CD settings => Runners,点击 New project runner 按钮,按步骤填写信息后,最后点击 Create runner。

然后在 GitLab-Runner 注册一个 Runner, 关联具体的仓库。执行 gitlab-runner register,按步骤填写信息,有个一坑是:url 填 ip 地址,不能填 localhost

  1. 创建 .gitlab-ci.yml 文件,提交文件后触发 GitLab Runner 执行 pipeline 任务
yml 复制代码
image: node:16-alpine

stages:
  - init
  - build
  - deploy

cache:
  key: ${CI_BUILD_REF_NAME}
  paths:
    - node_modules/
    - dist/

init:
  stage: init
  script:
    - npm install

build:
  stage: build
  script:
    - npm run build

deploy:
  image: docker
  stage: deploy
  script:
    - docker ps
    - docker build -t front-cicd-image .
    - if [ $(docker ps -aq --filter name=front-cicd-container) ]; then docker rm -f front-cicd-container;fi
    - docker run -d -p 8888:80 --name front-cicd-container front-cicd-image

在 Docker 打包部署时,项目根目录下要 Dockerfile 和 nginx.conf 配置文件,可以简单配置如下

Dockerfile

bash 复制代码
# build stage
FROM node:16-alpine as build-stage
WORKDIR /app
COPY . /app
RUN npm install && npm run build

# production stage
FROM nginx:latest as production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html
COPY --from=build-stage /app/nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

nginx.conf

bash 复制代码
server {
   listen    80;
  
   access_log  /var/log/nginx/host.access.log  main;
   error_log  /var/log/nginx/error.log  error;

   location / {
     root  /usr/share/nginx/html; 
     index  index.html index.htm;
   }
   
   error_page  500 502 503 504  /50x.html;
   location = /50x.html {
     root  html;
   }
}
  1. 一切顺利后,在 localhost:8888 访问前端项目

碰到的问题

postgresql 无法正常启动

最直观的反馈是本地 GitLab 访问显示 localhost refuse to connect,遂用 gitlab-ctl status 查看所有内置服务是否启动成功,发现 postgresql 一直在重试。

经查发现是新版的 Docker 默认使用 VirtioFS 模式用于文件共享,修改为 gRPC FUSE 即可,问题解决!

GitLab 界面报 502 错误

根据 gittal-ctl tail 查看日志发现一直提示 raven 3.1.2 configured not to capture errors DSN not set,但谷歌一直查不到错误的根源。遂从 502 错误码一个个排除网上常见的问题

  1. 判断端口是否被其他应用占用
  2. 判断容器空间是否满足

最终提高内存空间到 6G 后,终于登录页面出来了

GitLab Runner 无法使用 git 访问项目

具体报错信息为:fatal: unable to access http://ip/xxx/project.git Failed to connect to localhost port 80: Connection refused

项目都是本地容器化部署,容器内服务不能直接使用局域网 ip 访问,需修改网络模式为宿主 network_mode = "host",即与宿主机共用网络

GitLab Runner 报错:Is the docker daemon running?

错误很明显无法识别 docker 指令,解决办法让容器内使用宿主机的 docker.sock,修改容器文件如下

toml 复制代码
# /etc/gitlab-runner/config.toml
concurrent = 1
check_interval = 0
shutdown_timeout = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = "test"
  url = "http://192.168.1.3/"
  id = 14
  token = "glrt-ScfCBNPTAH6EzzF_SyCG"
  token_obtained_at = 2023-10-17T02:11:29Z
  token_expires_at = 0001-01-01T00:00:00Z
  executor = "docker"
  [runners.cache]
    MaxUploadedArchiveSize = 0
  [runners.docker]
    tls_verify = false
    image = "docker"
    privileged = false
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/cache"]
    shm_size = 0
    network_mode = "host" # 修改1
    volumes = ["/var/run/docker.sock:/var/run/docker.sock"] # 修改2
相关推荐
全栈工程师修炼指南7 小时前
告别手动构建!Jenkins 与 Gitlab 完美协作,根据参数自动化触发CI/CD流水线实践
运维·ci/cd·自动化·gitlab·jenkins
xiaok2 天前
分支管理提交代码
git·gitlab·github
*老工具人了*3 天前
Terraform整合到GitLab+Jenkins工具链
gitlab·jenkins·terraform
走上未曾设想的道路4 天前
中标麒麟7.4为gitlab添加Registry
gitlab
韩zj4 天前
docker部署Gitlab社区版,步骤以及外网访问出现502的解决方式
docker·容器·gitlab
走上未曾设想的道路4 天前
gitlab流水线与k8s集群的联通
kubernetes·gitlab
走上未曾设想的道路4 天前
中标麒麟7.4部署gitlab-runner
gitlab
xiaok5 天前
把代码上传到gitee的时候,怎么忽略node_modules文件夹
git·gitlab·github
deeper_wind5 天前
OpenEuler部署gitlab(小白的“升级打怪”成长之路)
gitlab
-KamMinG6 天前
“从零到一:使用GitLab和Jenkins实现自动化CI/CD流水线”
自动化·gitlab·jenkins