Gitlab CI 本地开发部署

gitlab ci 本地开发部署

整体架构说明

组件一共 3 部分:

  1. GitLab‑CE:代码仓库 + CI 调度中心(docker 部署)
  2. GitLab‑Runner:执行流水线任务,采用docker执行器(docker executor),挂载宿主机/var/run/docker.sock,job 会新建容器运行;
  3. 项目代码:项目根目录编写 .gitlab‑ci.yml。

环境前提:

  • 服务器:Linux (CentOS7 / Ubuntu22.04),内存 ≥4G,推荐 6G;
  • 已装好 docker、docker‑compose;
  • 关闭防火墙或者放行 80、443、2222 端口。

阶段 1:部署 GitLab‑CE(服务端)

1.1 编写 docker‑compose.yml

version: '3.8'
services:
  gitlab:
    image: gitlab/gitlab-ce:17.1.0-ce.0
    container_name: gitlab
    restart: always
    hostname: gitlab.local
    ports:
      - "80:80"
      - "443:443"
      - "2222:22"
    volumes:
      - ./config:/etc/gitlab
      - ./logs:/var/log/gitlab
      - ./data:/var/opt/gitlab
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'http://gitlab.local'
        gitlab_rails['gitlab_shell_ssh_port'] = 2222;
        # 设置最大并发CI任务,测试环境设2即可
        gitlab_rails['sidekiq_concurrency'] = 2;

1.2 启动容器

cd /opt/gitlab
docker-compose up -d

启动等待时间很长,大约 5‑10 分钟,所有组件初始化完毕。查看状态:

docker logs -f gitlab

1.3 获取初始管理员密码

# 进入容器查看root初始密码
docker exec -it gitlab grep 'Password:' /etc/gitlab/initial_root_password

复制密码,有效期 24 小时,登录后第一时间修改。

1.4 本地 hosts 解析(非常关键,否则 Runner 克隆代码失败)

  • Linux 服务器端 /etc/hosts 添加:

127.0.0.1 gitlab.local

  • 如果你自己电脑浏览器访问,本机 hosts 文件同样添加服务器 IP:

服务器IP gitlab.local

浏览器访问: http://gitlab.local ,使用root和上面密码登录,新建普通用户,然后新建项目。

阶段 2:部署 GitLab‑Runner

2.1 创建 runner 目录,编写 docker‑compose.yml

version: '3.8'
services:
  gitlab-runner:
    image: gitlab/gitlab-runner:alpine
    container_name: gitlab-runner
    restart: always
    volumes:
      - ./config:/etc/gitlab-runner
      # 核心:挂载宿主机docker,让job可以创建容器
      - /var/run/docker.sock:/var/run/docker.sock
    privileged: true
    environment:
      - TZ=Asia/Shanghai

启动 runner 容器:

cd /opt/gitlab-runner
docker-compose up -d

2.2 获取注册 Runner 所需要的参数

  1. 打开 GitLab 网页 → 进入你的项目 → 设置 → CI/CD → 运行程序 (Runner);
  2. 取消勾选【启用共享运行程序】;
  3. 获取两个值:

2.3 执行 runner 注册命令(重点)

进入 runner 容器内部执行注册:

docker exec -it gitlab-runner gitlab-runner register

按照下面依次填写:


# 1. 输入gitlab实例地址
Enter the GitLab instance URL (for example, https://gitlab.com/):
http://gitlab.local/

# 2. 粘贴项目里的注册token
Enter the registration token: 粘贴你的token

# 3. 填写runner描述,随便写:local-test-runner
Enter a description for the runner: local-test-runner

# 4. 标签(后面.gitlab‑ci.yml通过标签匹配runner):docker,test
Enter tags for the runner (comma‑separated): docker,test

# 5. 可选:是否仅针对受保护分支,测试环境填 false
Enter whether the runner should pick up jobs which are not tagged [true/false]: false

# 6. 选择执行器 executor 这里必须选 docker
Enter the executor: docker

# 7. CI job默认基础镜像,根据你的项目填写,这里以golang举例,PHP就填php:8.3‑cli‑alpine
Enter the default Docker image (for example, ruby:2.7): golang:1.23-alpine


注册完成后,页面刷新,Runner 显示绿色,代表就绪。

查看 runner 配置文件(确认配置)

cat /opt/gitlab-runner/config/config.toml

config.toml 配置文件如下

concurrent = 1
check_interval = 0
connection_max_age = "15m0s"
shutdown_timeout = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = "gitlab-runner-test"
  url = "http://gitlab.local/"
  id = 2
  token = "xfGsxCefUwH2Fq5sU-Fs"
  token_obtained_at = 2026-07-16T02:13:16Z
  token_expires_at = 0001-01-01T00:00:00Z
  executor = "docker"
  [runners.cache]
    MaxUploadedArchiveSize = 0
    [runners.cache.s3]
      AssumeRoleMaxConcurrency = 0
    [runners.cache.gcs]
    [runners.cache.azure]
  [runners.docker]
    tls_verify = false
    image = "golang:1.26-alpine3.23"
    privileged = true # 开启 Docker 特权模式,挂载宿主机的docker.sock,实现 Docker‑in‑Docker(DinD),容器内部可以再启动 docker 容器
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"] # 将宿主机的 Docker 守护进程套接字挂载进容器,实现宿主机 Docker 复用(DinD 经典用法)
    volume_keep = false
    shm_size = 0
    network_mtu = 0
    extra_hosts = ["gitlab.local:host-gateway"] # 给容器的 /etc/hosts 添加域名解析:host‑gateway是 Docker 内置特殊值,指向宿主机 IP,在 CI 容器里访问域名 gitlab.local 会解析到宿主机 IP,适用于内网 GitLab 场景,容器里可以访问宿主机上的 GitLab 服务
    pull_policy = ["if-not-present"] # 镜像本地存在就不拉取,加快构建速度,测试环境非常实用

阶段 3:编写 CI 配置文件 .gitlab‑ci.yml(项目代码里)

在项目根目录新建 .gitlab‑ci.yml,示例以 Go 项目举例


# 指定runner标签,匹配刚刚注册的标签
default:
  tags:
    - docker
    - test

# 流水线分阶段:构建、单元测试、部署
stages:
  - build
  - test
  - deploy

# 构建阶段
build_app:
  stage: build
  image: golang:1.23-alpine
  script:
    - go version
    - go mod tidy
    - go build -o myapp main.go
  artifacts:
    paths:
      - myapp # 将编译产物保存,后面阶段可以下载

# 单元测试阶段
unit_test:
  stage: test
  image: golang:1.23-alpine
  script:
    - go test ./... -v

# 部署阶段(仅main分支执行)
deploy_dev:
  stage: deploy
  image: alpine:latest
  only:
    - main
  script:
    - echo "开始部署到测试服务器"
    - ls -l myapp

阶段 4:查看流水线运行结果

  1. GitLab 页面 → CI/CD → 流水线 (Pipelines);
  2. 提交代码之后自动触发流水线;
  3. 可以点进 job 查看日志,看每一条命令执行情况;
  • 绿色对勾:执行成功;
  • 红色:失败,查看日志排错。

常见踩坑总结(本地环境高频问题)

  • GitLab 内存不足:sidekiq 进程挂掉,任务一直 pending,必须内存≥4G;
  • gitlab.local 解析失败:服务器和本地电脑都要配置 hosts,不能只用 127.0.0.1;
  • Runner 无法拉取镜像:在config.toml里配置[[runners.docker.tls_verify]]关闭私有仓库 https 校验;
  • 执行器选错:runner 注册 executor 一定选 docker,不要选 shell;
  • 标签不匹配:.gitlab‑ci.yml里 tags 必须和 runner 注册时填写的 tags 一致,否则 Job 排队不执行。

PHP语言的 .gitlab-ci.yml (Laravel 版,可直接使用)示例


# 匹配runner标签
default:
  tags:
    - docker
    - test

# 缓存composer依赖,不同分支共用缓存
cache:
  paths:
    - vendor/
    - composer.lock
  key:
    files:
      - composer.lock
  policy: pull-push

# 流水线阶段定义
stages:
  - install
  - lint
  - test
  - deploy-dev

# 1.安装依赖
composer_install:
  stage: install
  image: php:8.3-cli-alpine
  before_script:
    # 安装系统依赖、php扩展
    - apk update && apk add --no-cache git curl openssh-client
    - docker-php-ext-install pdo_mysql
    - curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
  script:
    - composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
    - composer install --optimize-autoloader --no-scripts
  artifacts:
    paths:
      - vendor/
      - composer.lock

# 2.代码语法检查 php‑cs‑fixer
php_lint:
  stage: lint
  image: php:8.3-cli-alpine
  before_script:
    - apk add git
    - curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
  script:
    - composer global require friendsofphp/php-cs-fixer
    - ~/.composer/vendor/bin/php-cs-fixer fix --dry-run --diff .
  dependencies:
    - composer_install

# 3.单元测试 PHPUnit
phpunit_test:
  stage: test
  image: php:8.3-cli-alpine
  before_script:
    - apk add git
    - docker-php-ext-install pdo_mysql
  script:
    - php artisan test
  dependencies:
    - composer_install

# 4.部署到测试服务器 develop分支自动部署
deploy_dev:
  stage: deploy-dev
  image: alpine:latest
  only:
    - develop
  before_script:
    - apk add --no-cache openssh-client rsync
    # GitLab CI后台配置环境变量 DEPLOY_SERVER、DEPLOY_USER、DEPLOY_PASS、DEPLOY_DIR
  script:
    - mkdir -p ~/.ssh
    - eval $(ssh-agent -s)
    - echo "$DEPLOY_PASS" | ssh-add -
    - ssh-keyscan $DEPLOY_SERVER >> ~/.ssh/known_hosts
    # 同步代码至服务器,排除 .git、.gitlab‑ci.yml
    - rsync -av --delete --exclude=".git" --exclude=".gitlab-ci.yml" ./ $DEPLOY_USER@$DEPLOY_SERVER:$DEPLOY_DIR
    # 远程执行命令,清理缓存
    - ssh $DEPLOY_USER@$DEPLOY_SERVER "cd $DEPLOY_DIR && php artisan optimize && php artisan migrate --force"
  dependencies:
    - composer_install


避坑要点

  1. 本地测试环境 gitlab‑runner 的 config.toml 里:
    pull_policy = ["if-not-present"],镜像本地存在就不会重复下载,加快构建;

  2. 若不想每次自动部署 main 分支,给 deploy 阶段加上:
    when: manual,只有手动点击流水线任务才执行部署;
    php 扩展按需增加,比如 redis:docker-php-ext-install redis。

posted @ 2026-07-16 11:10  zakun  阅读(53)  评论(0)    收藏  举报
返回顶部