2025 版 GitLab 完整搭建指南:Docker Compose 部署 + Runner 注册 + CICD 配置
概述
GitLab 作为集 “代码托管、CI/CD 流水线、项目管理” 于一体的开源工具,是团队协作开发的核心载体。相比 GitHub 或 Gitee 私有仓库,自建 GitLab 能更灵活地控制数据隐私与流水线流程。
本文基于 Docker Compose 实现 GitLab 快速部署(含 GitLab CE 核心服务与 GitLab Runner 执行器),并提供从 “环境启动” 到 “Runner 注册”,再到 “项目 CI/CD 配置” 的全流程操作,适配 2025 年最新的 GitLab 17.7.0 版本,新手可按步骤复刻,团队可直接复用配置文件落地生产。
一、核心准备:环境与依赖检查
在开始搭建前,确保服务器满足以下基础条件,避免后续启动失败或性能卡顿:
1. 服务器配置要求
- 硬件:至少 4GB 内存(GitLab 服务占用较高,2GB 内存可能频繁崩溃)、20GB 磁盘空间(用于存储代码、日志与 Runner 缓存);
- 系统:Linux 发行版(如 Ubuntu 22.04、CentOS 9,本文以 Linux 为例,macOS 需调整挂载路径权限);
- 软件:已安装 Docker 与 Docker Compose(若未安装,需先执行以下命令):
# 安装 Docker(以 Ubuntu 为例,其他系统参考官方文档)
sudo apt update && sudo apt install -y docker.io
# 安装 Docker Compose
sudo apt install -y docker-compose-plugin
# 验证安装:查看版本
docker --version && docker compose version
2. 网络与域名准备
- 端口占用:确保服务器 8929(GitLab Web 端口)、2424(GitLab SSH 端口)未被占用,可通过 netstat -tuln | grep 8929 检查;
- 域名解析:提前将 gitlab.luojia.work(配置文件中的 hostname)解析到服务器 IP,若仅本地测试,可修改 /etc/hosts 添加映射(如 192.168.1.100 gitlab.luojia.work)。
二、Step 1:编写 Docker Compose 配置文件
通过 docker-compose.yml 统一管理 GitLab 核心服务与 Runner 服务,实现 “一键启动” 与 “数据持久化”。配置文件中已包含版本锁定、端口映射、数据挂载等关键配置,可直接复制使用(需根据实际需求微调域名与端口)。
1. 创建配置文件与目录
# 1. 创建 GitLab 工作目录(统一管理配置、日志、数据)
mkdir -p ~/gitlab-docker && cd ~/gitlab-docker
# 2. 创建 volumes 子目录(用于挂载数据,避免容器删除后数据丢失)
mkdir -p volumes/config volumes/logs volumes/data
# 3. 编写 docker-compose.yml 文件(用 vim 或 nano 均可)
vim docker-compose.yml
2. 完整配置文件内容
services:
# GitLab 核心服务(CE 社区版,免费且功能满足大部分团队需求)
gitlab:
image: gitlab/gitlab-ce:17.7.0-ce.0 # 锁定 17.7.0 版本,避免自动更新导致兼容问题
container_name: roger-gitlab # 容器名,便于后续管理(如停止、进入容器)
restart: always # 容器异常退出时自动重启(保证服务可用性)
hostname: "gitlab.luojia.work" # GitLab 内部 hostname,需与 external_url 域名一致
environment:
# GitLab 核心配置:通过环境变量注入,无需进入容器修改配置文件
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://gitlab.luojia.work:8929' # 外部访问地址(含端口)
gitlab_rails['gitlab_shell_ssh_port'] = 2424 # Git SSH 访问端口(默认 22,避免与主机 22 冲突)
ports:
- "8929:8929" # Web 端口映射:主机 8929 → 容器 8929(外部通过 http://域名:8929 访问)
- "2424:22" # SSH 端口映射:主机 2424 → 容器 22(Git 克隆时用 ssh://git@域名:2424/项目.git)
volumes:
# 数据持久化挂载:将容器内关键目录挂载到主机,确保容器删除后数据不丢失
- "./volumes/config:/etc/gitlab" # GitLab 配置文件目录
- "./volumes/logs:/var/log/gitlab" # GitLab 日志目录(排查问题时需查看)
- "./volumes/data:/var/opt/gitlab" # GitLab 数据目录(代码、数据库等核心数据)
shm_size: "256m" # 共享内存大小(GitLab 部分功能依赖,避免内存不足报错)
# GitLab Runner 服务(用于执行 CI/CD 流水线任务,如代码构建、部署)
gitlab-runner:
image: gitlab/gitlab-runner:v17.7.0 # Runner 版本需与 GitLab 版本匹配(避免 API 不兼容)
container_name: roger-gitlab-runner # Runner 容器名
restart: always
depends_on:
- gitlab # 确保 GitLab 服务启动后,再启动 Runner(避免 Runner 先启动无法连接 GitLab)
volumes:
# 挂载 Docker 套接字:让 Runner 能在容器内调用主机 Docker(实现 Docker 镜像构建)
- "/var/run/docker.sock:/var/run/docker.sock"
# 挂载 Runner 配置目录:持久化 Runner 注册信息(避免容器重启后需重新注册)
- "./volumes/config/gitlab-runner:/etc/gitlab-runner"
# 挂载主机 Docker 二进制文件:确保 Runner 内 Docker 命令可用(部分环境需此配置)
- "./volumes/bin/docker:/usr/bin/docker"
command: ["run", "--user=root", "--working-directory=/home/gitlab-runner"]
# 赋予特权模式:解决 Runner 内操作 Docker 时的权限问题(生产环境需评估安全性,非必需可删除)
privileged: true
3. 配置关键参数说明
参数 | 作用 | 修改建议 |
---|---|---|
external_url | 外部访问 GitLab 的 URL,决定网页访问与 Git 克隆地址 | 需改为实际域名 + 端口(如 http://gitlab.your-domain.com:8080) |
gitlab_shell_ssh_port | Git SSH 协议端口 | 若主机 22 端口未被占用,可改为 22(克隆地址更简洁:git@域名:项目.git) |
ports | 端口映射 | 避免与主机现有服务冲突(如 80 端口可用,可将 8929 改为 80) |
volumes | 数据挂载 | 建议使用绝对路径(如 /home/user/gitlab-docker/volumes/config),避免路径混乱 |
三、Step 2:启动 GitLab 与 Runner 服务
配置文件编写完成后,通过 Docker Compose 启动服务。首次启动需初始化数据库与配置,耗时较长(约 5-10 分钟,取决于服务器性能),需耐心等待。
1. 启动服务
# 后台启动服务(-d 表示 detached 模式,日志不会打印到控制台)
docker compose up -d
# 查看服务启动状态(确认 gitlab 与 gitlab-runner 均为 Up 状态)
docker compose ps
# 查看 GitLab 初始化日志(可选,监控初始化进度,出现 "Configuration finished" 表示初始化完成)
docker logs -f roger-gitlab
2. 验证 GitLab 网页访问
当日志显示初始化完成后,打开浏览器访问 http://gitlab.luojia.work:8929(或你配置的 external_url):
- 首次访问会提示 “设置管理员密码”(用户名默认 root),设置完成后登录;
- 若无法访问,检查服务器防火墙(如 sudo ufw allow 8929 开放端口)或 Docker 网络(docker network inspect gitlab-docker_default)。
四、Step 3:配置 Docker 权限(关键步骤)
GitLab Runner 需要调用主机 Docker 服务构建镜像,但默认 /var/run/docker.sock(Docker 套接字文件)权限为 root:docker,Runner 容器内用户无访问权限,需手动调整权限。
# 修改 docker.sock 权限为 666(允许所有用户读写,简单高效,适合内部测试环境)
sudo chmod 666 /var/run/docker.sock
# 验证权限(输出 "-rw-rw-rw-" 表示权限修改成功)
ls -l /var/run/docker.sock
注意事项(生产环境优化):
- 直接设置 666 权限存在安全风险(所有用户可操作 Docker),生产环境建议:
- 在主机创建 docker 用户组(若不存在):sudo groupadd docker;
- 将 Runner 容器内用户加入主机 docker 组:sudo usermod -aG docker gitlab-runner;
- 恢复 docker.sock 权限为 660:sudo chmod 660 /var/run/docker.sock。
五、Step 4:注册 Runner 到 GitLab
Runner 是执行 CI/CD 任务的 “工人”,需先注册到 GitLab 并绑定项目,才能接收任务。注册过程需获取 GitLab 的 “注册令牌”,步骤如下:
1. 获取 GitLab 注册令牌
1.登录 GitLab 网页后台(root 账号); 2. 进入 “Admin Area”(管理员区域,左侧导航栏最下方)→ “Runners” → “New instance runner”; 3. 按提示选择 Runner 类型(此处选 “Docker”),获取 “Registration token”(注册令牌,后续步骤需用到)。
2. 执行 Runner 注册命令
# 进入 Runner 容器,执行注册命令(容器名与配置文件中 container_name 一致)
docker exec -it roger-gitlab-runner gitlab-runner register
3. 按提示完成注册(关键步骤)
注册过程会弹出交互提示,按以下说明填写(其他默认选项直接回车):
# 1. 输入 GitLab 实例 URL(与 external_url 一致)
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
http://gitlab.luojia.work:8929
# 2. 输入刚才获取的注册令牌
Please enter the gitlab-ci token for this runner:
abcdefghijklmnopqrst # 替换为你的 Registration token
# 3. 输入 Runner 描述(自定义,便于识别,如 "Docker Runner for Build")
Please enter the gitlab-ci description for this runner:
[roger-gitlab-runner]: Docker Build Runner
# 4. 输入 Runner 标签(关键!CI/CD 配置中需通过标签指定 Runner,此处填 "docker")
Please enter the gitlab-ci tags for this runner (comma separated):
docker
# 5. 选择 Runner 执行器(此处选 "docker",因为我们要通过 Docker 构建镜像)
Please enter the executor: custom, docker, docker-ssh, parallels, shell, ssh, virtualbox, docker+machine, docker-ssh+machine, kubernetes:
docker
# 6. 若选择 docker 执行器,需指定默认 Docker 镜像(填 "alpine:latest" 即可,轻量且通用)
Please enter the default Docker image (e.g. ruby:2.7):
alpine:latest
4. 验证 Runner 注册成功
回到 GitLab 网页后台 “Admin Area → Runners”,若能看到状态为 “Active” 的 Runner(标签含 docker),表示注册成功。
六、Step 5:配置项目 CI/CD 流水线(.gitlab-ci.yml)
Runner 注册完成后,需在 GitLab 项目中添加 .gitlab-ci.yml 文件,定义 “构建(build)→ 部署(deploy)” 的流水线流程。以下示例实现 “Docker 镜像构建 → 部署到 Kubernetes 集群”,可根据实际需求调整脚本。
1. 前置准备(项目级配置)
在 GitLab 项目中添加 “环境变量”(避免敏感信息硬编码到配置文件):
- 进入项目 → “Settings” → “CI/CD” → “Variables” → “Add variable”;
- 添加以下变量(均设为 “Protected” 和 “Masked”,避免泄露):
- IMAGE_NAME:Docker 镜像名(如 my-project);
- IMAGE_TAG:Docker 镜像标签(如 $CI_COMMIT_SHORT_SHA,自动取当前提交的短哈希);
- SSH_KEY:用于登录部署服务器的 SSH 私钥(需提前在部署服务器添加公钥);
- DEPLOY_USER:部署服务器用户名(如 root);
- DEPLOY_HOST:部署服务器 IP(如 192.168.1.101);
- K8S_CONFIG_PATH:Kubernetes 部署配置文件路径(如 k8s/deployment.yaml)。
2. 编写 .gitlab-ci.yml 文件
在项目根目录创建 .gitlab-ci.yml,内容如下:
# 定义流水线阶段(顺序执行:先 build 再 deploy,可新增 test 等阶段)
stages:
- build # 构建阶段:构建 Docker 镜像
- deploy # 部署阶段:将镜像部署到 Kubernetes 集群
# 构建任务(属于 build 阶段)
build:
stage: build
tags:
- docker # 指定使用标签为 "docker" 的 Runner(与注册 Runner 时的标签一致)
script:
# 构建 Docker 镜像(镜像名+标签从环境变量获取,避免硬编码)
- docker build -t $IMAGE_NAME:$IMAGE_TAG .
# 可选:将镜像推送到私有仓库(如 GitLab Container Registry)
# - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
# - docker push $CI_REGISTRY/$CI_PROJECT_PATH/$IMAGE_NAME:$IMAGE_TAG
# 部署任务(属于 deploy 阶段,依赖 build 阶段完成)
deploy:
stage: deploy
tags:
- docker
before_script:
# 给 SSH 私钥设置只读权限(SSH 要求私钥权限不能过高,否则报错)
- chmod 400 $SSH_KEY
script:
# 通过 SSH 登录部署服务器,执行部署命令(一行命令用双引号包裹,多命令用分号分隔)
- ssh -o StrictHostKeyChecking=no -i $SSH_KEY ${DEPLOY_USER}@${DEPLOY_HOST} "
# 1. 将本地构建的镜像加载到 Kubernetes 集群(kind 是轻量 K8s 工具,根据实际环境调整)
kind load docker-image $IMAGE_NAME:$IMAGE_TAG --name roger &&
# 2. 应用 Kubernetes 部署配置,更新服务
kubectl apply -f $K8S_CONFIG_PATH
"
# 可选:仅在 master/main 分支提交时触发部署(避免测试分支误部署)
only:
- master
3. 触发流水线并验证
- 将 .gitlab-ci.yml 提交到 GitLab 项目(git add . && git commit -m "add ci/cd config" && git push);
- 进入项目 → “CI/CD” → “Pipelines”,可看到流水线自动触发,状态从 “pending” 变为 “running”;
- 点击流水线任务,查看 “Job log”,若最后显示 “Job succeeded”,表示构建与部署均成功。
七、常见问题与解决方案
1. GitLab 启动后网页无法访问
- 检查防火墙端口:若使用 Ubuntu 系统,通过 sudo ufw status 确认 8929 端口已开放,未开放则执行 sudo ufw allow 8929;CentOS 系统需检查 firewalld,执行 sudo firewall-cmd --zone=public --add-port=8929/tcp --permanent 并 sudo firewall-cmd --reload。
- 排查容器日志:执行 docker logs -f roger-gitlab 查看初始化日志,若出现 “database connection timeout” 或 “memory exhausted”,大概率是服务器内存不足(GitLab 最低需 4GB 内存),需升级服务器配置或关闭其他占用内存的服务。
- 验证 external_url 一致性:确保浏览器访问地址与 docker-compose.yml 中 external_url 完全一致(含域名、端口),例如配置的是 http://gitlab.luojia.work:8929,则不能用 http://192.168.1.100:8929 访问(除非 /etc/hosts 已配置域名映射)。
2. Runner 注册时提示 “connection refused”
- 确认 GitLab 服务状态:先通过 docker compose ps 检查 roger-gitlab 容器是否为 Up 状态,若为 Exited,需先重启服务 docker compose restart gitlab。
- 检查网络连通性:进入 Runner 容器内部测试网络,执行 docker exec -it roger-gitlab-runner ping gitlab.luojia.work,若无法 ping 通,需检查 Docker 网络(默认 bridge 模式下,容器间可通过容器名或 hostname 通信,若自定义网络需调整)。
- 核对注册令牌与 URL:确保输入的 GitLab 实例 URL(如 http://gitlab.luojia.work:8929)末尾无多余斜杠,注册令牌与 GitLab 后台 “Admin Area → Runners” 中显示的完全一致(区分大小写)。
3. CI/CD 流水线提示 “docker: command not found”
- 检查 Docker 挂载配置:确认 docker-compose.yml 中 Runner 服务的 volumes 已包含 /var/run/docker.sock:/var/run/docker.sock,若遗漏需添加后重启 Runner:docker compose restart gitlab-runner。
- 验证 Docker 权限:进入 Runner 容器执行 ls -l /var/run/docker.sock,若显示 “Permission denied”,需重新执行 sudo chmod 666 /var/run/docker.sock(测试环境)或按前文 “生产环境优化” 方案配置 docker 用户组权限。
- 检查 Docker 二进制文件:若配置了 - "./volumes/bin/docker:/usr/bin/docker" 挂载,需确认主机 /home/user/gitlab-docker/volumes/bin/docker 路径下存在 docker 二进制文件,若不存在可从主机 /usr/bin/docker 复制:cp /usr/bin/docker ~/gitlab-docker/volumes/bin/。
4. SSH 部署时提示 “Host key verification failed”
- 关闭 StrictHostKeyChecking:在 deploy 任务的 ssh 命令中添加 -o StrictHostKeyChecking=no(已在示例配置中包含),跳过首次连接的主机密钥验证(适合自动化场景,生产环境可提前在 Runner 容器中添加部署服务器的主机密钥)。
- 验证 SSH 私钥有效性:在 GitLab 项目 “CI/CD → Variables” 中检查 SSH_KEY 变量是否完整(无多余空格、换行),可在本地测试私钥:ssh -i ~/local-ssh-key deploy-user@deploy-host,确保能正常登录。
- 检查私钥权限:确认 before_script 中的 chmod 400 $SSH_KEY 已执行(SSH 要求私钥权限不能高于 600,否则拒绝使用),若仍报错,可在脚本中添加 ls -l $SSH_KEY 查看权限是否正确。
5. Kubernetes 部署提示 “kind: command not found”
- 确认部署服务器环境:kind load docker-image 命令仅适用于使用 Kind(Kubernetes IN Docker)搭建的 K8s 集群,若部署目标是真实 K8s 集群(如 EKS、AKS 或自建集群),需替换为 docker push 镜像到集群可访问的镜像仓库(如 Docker Hub、GitLab Container Registry),再通过 kubectl apply 部署。
- 检查 kubectl 配置:确保部署服务器已安装 kubectl 且配置了集群访问权限(~/.kube/config 文件正常),可在部署服务器本地执行 kubectl get nodes 验证,若报错需先配置 K8s 集群访问凭证。
八、总结与后续优化建议
1. 搭建成果回顾
通过本文步骤,已实现:
- GitLab 核心服务部署:基于 Docker Compose 实现一键启动,数据持久化存储(配置、日志、代码数据不丢失);
- Runner 注册与绑定:Runner 能正常接收 GitLab 下发的 CI/CD 任务,支持 Docker 镜像构建;
- 完整 CI/CD 流水线:从代码提交触发构建,到镜像部署到 Kubernetes 集群,实现自动化流程。
2. 生产环境优化方向
(1)安全性增强
- 替换 HTTP 为 HTTPS:在 docker-compose.yml 中修改 external_url 为 https://gitlab.your-domain.com,并通过 GITLAB_OMNIBUS_CONFIG 配置 SSL 证书(如使用 Let's Encrypt 免费证书):
GITLAB_OMNIBUS_CONFIG: |
external_url 'https://gitlab.your-domain.com'
nginx['ssl_certificate'] = "/etc/gitlab/ssl/gitlab.your-domain.com.crt"
nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/gitlab.your-domain.com.key"
- 限制 Runner 权限:生产环境避免使用 privileged: true,改为通过 docker 用户组授权(前文已提及),并限制 Runner 仅能访问必要的项目(在 GitLab 后台 “Runner → Restrict projects” 中配置)。
- 加密敏感变量:GitLab 项目的 CI/CD 变量需勾选 “Masked”(隐藏变量值)和 “Protected”(仅保护分支可使用),避免敏感信息泄露。
(2)性能与可用性优化
- 增加资源限制:在 docker-compose.yml 中为 GitLab 服务添加资源限制,避免占用过多服务器资源:
services:
gitlab:
# 其他配置...
deploy:
resources:
limits:
cpus: "2"
memory: 4G
reservations:
cpus: "1"
memory: 2G
- 配置 GitLab 备份:添加定时任务自动备份 GitLab 数据(通过 gitlab-rake gitlab:backup:create 命令),并将备份文件同步到异地存储(如 S3、OSS):
# 示例:每天凌晨 2 点执行备份,输出到 /backup 目录
0 2 * * * docker exec roger-gitlab gitlab-rake gitlab:backup:create BACKUP_DIR=/var/opt/gitlab/backups && cp ~/gitlab-docker/volumes/data/backups/*.tar /backup/
- 使用 GitLab Container Registry:启用 GitLab 内置的镜像仓库(项目 → “Packages & Registries → Container Registry”),避免依赖外部镜像仓库,简化流水线流程(示例配置中已包含推送镜像的注释代码)。
(3)功能扩展
- 添加 GitLab Pages:配置 GitLab Pages 实现静态网站部署(如项目文档、博客),需在 GITLAB_OMNIBUS_CONFIG 中添加 pages_external_url 'https://pages.your-domain.com/';
- 集成 Mattermost/Teams:配置 GitLab 通知,将流水线状态、代码提交信息推送到团队沟通工具(如 Mattermost、Microsoft Teams),提升协作效率;
- 启用 LDAP 认证:若团队使用 LDAP 统一身份认证,可在 GitLab 后台 “Admin Area → Settings → General → Sign-in restrictions” 中配置 LDAP 登录,实现单点登录。
通过以上优化,自建的 GitLab 可从 “基础可用” 升级为 “生产级稳定服务”,满足团队从代码托管到自动化部署的全流程需求。后续可根据团队规模与业务场景,逐步扩展功能,充分发挥 GitLab 的生态优势。