惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
宝玉的分享
宝玉的分享
P
Proofpoint News Feed
I
Intezer
云风的 BLOG
云风的 BLOG
A
About on SuperTechFans
aimingoo的专栏
aimingoo的专栏
Y
Y Combinator Blog
小众软件
小众软件
T
Threatpost
B
Blog
美团技术团队
博客园 - 司徒正美
T
The Exploit Database - CXSecurity.com
T
Tailwind CSS Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Cyberwarzone
Cyberwarzone
雷峰网
雷峰网
The GitHub Blog
The GitHub Blog
T
Tenable Blog
A
Arctic Wolf
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Security Archives - TechRepublic
Security Archives - TechRepublic
博客园 - 叶小钗
L
Lohrmann on Cybersecurity
博客园 - 三生石上(FineUI控件)
L
LINUX DO - 热门话题
J
Java Code Geeks
Google DeepMind News
Google DeepMind News
S
Security Affairs
Simon Willison's Weblog
Simon Willison's Weblog
K
Kaspersky official blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
GbyAI
GbyAI
N
News and Events Feed by Topic
Cloudbric
Cloudbric
WordPress大学
WordPress大学
量子位
W
WeLiveSecurity
H
Hacker News: Front Page
Project Zero
Project Zero
S
Security @ Cisco Blogs
Security Latest
Security Latest
Hugging Face - Blog
Hugging Face - Blog
Forbes - Security
Forbes - Security
C
Cybersecurity and Infrastructure Security Agency CISA
人人都是产品经理
人人都是产品经理
U
Unit 42
Know Your Adversary
Know Your Adversary
Google Online Security Blog
Google Online Security Blog

博客园 - zakun

适配 WSL 的 proxy 完整脚本 Golang grpc 实践 Mongo 聚合演示 真・一键激活 JetBrains 全家桶! Kafka 分区细说 解决国内Homebrew安装 Homebrew How to Install PHP Install Elasticsearch with Docke wsl2 网络相关设置 php docker image nginx 反向代理常用设置说明 Golang常见的并发模式 Gin框架的几种热加载方法 协程 Mysql Full-Text Index 介绍 gitlab runner 使用摘要 Gitlab Docker 使用摘要 Docker 简介 linux-查看文件夹大小 Linux 如何删除乱码文件-inode删除 Nginx反爬虫: 禁止某些User Agent抓取网站 PHP添加$_SERVER服务器环境变量
Gitlab CI 本地开发部署
zakun · 2026-07-16 · via 博客园 - zakun

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‑runnerconfig.toml 里:
    pull_policy = ["if-not-present"],镜像本地存在就不会重复下载,加快构建;

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