GitLab 私服从 0 到 1:部署、Runner、备份、升级与安全基线

本文面向想在公司内网、家庭实验室或小团队中搭建 GitLab 私服的开发者与运维人员。目标不是“把 GitLab 跑起来就完事”,而是把部署、域名、HTTPS、Runner、备份、恢复、升级和安全基线一次性讲清楚。GitLab 私服不是装个代码仓库那么简单,它更像一个“小型 DevOps 中枢”:好用是真好用,裸奔也是真容易把自己坑成午夜运维。

1. GitLab 私服到底是什么

GitLab 私服通常指 GitLab Self-Managed,也就是把 GitLab 部署在自己的服务器、虚拟机、NAS、Kubernetes 或私有云上,由自己负责数据、网络、安全、升级和备份。

它能提供的不只是 Git 仓库,还包括:

  • 代码托管:Group、Project、Branch、Merge Request、Code Review。
  • 权限管理:用户、组、项目、保护分支、访问令牌。
  • CI/CD:.gitlab-ci.yml、Pipeline、Job、Artifacts、Environments。
  • 制品管理:Container Registry、Package Registry、Release。
  • 项目协作:Issue、Milestone、Wiki、Snippet。
  • 安全治理:2FA、注册限制、Rate Limit、审计与合规能力,不同能力取决于版本和订阅。

如果你只是个人用,GitLab 会显得有点“重”;如果你有多个项目、多人协作、CI/CD、内部制品仓库需求,它就很香。GitLab 的正确打开方式不是“一个 Web 版 Git”,而是“代码到交付的控制面板”。

2. 什么时候适合自建 GitLab

适合自建的场景:

  1. 代码不能上公有 SaaS:公司合规、客户约束、内网开发、涉密项目。
  2. 需要统一 DevOps 平台:代码、MR、CI/CD、镜像、制品、权限都想统一。
  3. 需要和内网系统集成:LDAP/AD、内网 DNS、内部镜像仓库、K8s、制品库。
  4. 有可维护的人:能定期升级、看日志、测恢复、处理磁盘和证书问题。

不适合自建的场景:

  1. 只有一两个人写代码,也没有 CI/CD,Gitea、Forgejo 可能更轻。
  2. 没有人负责备份和升级,GitLab 私服会变成“定时炸弹”。
  3. 想要高可用但预算极低。GitLab HA 不是再开两个容器那么简单,PostgreSQL、Redis、Gitaly、Praefect、对象存储都要考虑。

一句话:GitLab 私服适合“愿意为掌控权付出运维成本”的团队。

3. 部署方式怎么选

GitLab 官方提供多种安装方式。常见选择如下:

方式 适合场景 优点 风险/缺点
Linux package / Omnibus 生产单机、小中型团队 官方成熟方案,安装和升级相对简单,很多组件打包好 和宿主机耦合较深,迁移要规划
Docker Compose 家庭实验室、小团队、快速验证 文件化部署,迁移方便,路径清晰 容器本身很重,升级和持久化必须谨慎
Kubernetes / Helm / Operator 已有 K8s 平台的大团队 云原生、弹性、可拆分 复杂度高,不建议为了 GitLab 专门上 K8s
Self-compiled 特殊定制、源码研究 灵活 运维复杂,不建议普通生产使用

我的建议:

  • 个人/家庭/小团队内网:优先 Docker Compose。
  • 企业单机生产:优先 Linux package / Omnibus。
  • 大规模生产:参考 GitLab Reference Architecture,而不是“单机硬扛”。
  • 已有成熟 K8s 平台:再考虑 Helm/Operator;没有 K8s 的话别为了 GitLab 硬上,别把 DevOps 变成 DevOops。

4. 资源规划:CPU、内存、磁盘和端口

4.1 最低资源建议

官方文档提到,Linux package 安装包本身大约需要 2.5GB 存储;结合 PostgreSQL、日志、临时文件和操作系统开销,即使没有仓库数据,也建议为基础安装预留至少 40GB 磁盘。实际生产中,磁盘应按仓库、Artifacts、LFS、Package、Registry、备份增长量来估算。

经验建议:

规模 CPU 内存 磁盘 说明
个人/实验 2 核 4GB 起步,8GB 更稳 80GB+ SSD 能跑,但别指望很丝滑
小团队 4 核 8GB-16GB 200GB+ SSD 推荐起点
中型团队 8 核+ 16GB-32GB+ 500GB+ SSD/NVMe 需要监控与调优
大规模 参考官方架构 参考官方架构 对象存储/独立 PostgreSQL/Gitaly 不建议靠单机经验拍脑袋

磁盘优先用 SSD/NVMe。GitLab 对磁盘 IO 比你想象的敏感,机械盘会让 MR 页面、CI 日志、仓库操作一起“修仙”。

4.2 端口规划

常见端口:

端口 用途 说明
80 HTTP / Let’s Encrypt 验证 公网 HTTPS 自动证书通常需要
443 HTTPS 推荐使用
22 Git over SSH 如果宿主机 SSH 已占用,可映射到 2424 等
5050 Container Registry 可选,视配置而定

如果你的服务器已经用 22 端口登录系统,不建议让 GitLab 直接抢 22。可以把 GitLab SSH 映射到 2424,然后在 GitLab 配置里同步设置 gitlab_shell_ssh_port,否则页面展示的 SSH clone 地址会不对。

5. 域名与访问模式

部署前先决定访问方式,后面再改会牵涉 clone 地址、Webhook、OAuth、Pages、Registry、WebAuthn 等一堆东西。

推荐:

1
2
3
gitlab.example.com       -> GitLab Web / API
registry.example.com -> Container Registry,可选
pages.example.com -> GitLab Pages,可选

内网环境可以用:

1
2
3
gitlab.lan
gitlab.home.arpa
gitlab.egon.local

但要注意:

  • 浏览器和 Git 客户端都要能解析这个域名。
  • external_url 必须写用户真实访问 GitLab 的地址。
  • 一旦换域名,用户本地仓库 remote URL 也要改。
  • WebAuthn 这类安全设备和域名绑定,迁移 FQDN 会带来额外影响。

家庭或小公司内网的推荐模式:

  1. 只内网使用:内网 DNS + HTTP 或内网 CA HTTPS。
  2. 远程访问:优先 VPN/WireGuard,再访问内网 GitLab。
  3. 必须公网开放:公网 DNS + HTTPS + 关闭公开注册 + 强制 2FA + 限制管理入口。

6. 方案 A:Docker Compose 部署 GitLab

Docker Compose 适合内网、小团队和实验环境。它的核心是三类持久化目录:

1
2
3
/srv/gitlab/config  -> /etc/gitlab
/srv/gitlab/logs -> /var/log/gitlab
/srv/gitlab/data -> /var/opt/gitlab

6.1 创建目录

1
2
sudo mkdir -p /srv/gitlab/{config,logs,data}
sudo chown -R root:root /srv/gitlab

6.2 编写 docker-compose.yml

下面使用自定义 HTTP 端口 8929 和 SSH 端口 2424,适合宿主机 80/443/22 已被其他服务占用的场景。

生产环境请把 <version> 替换成明确版本,例如 18.x.x 对应的镜像标签。不要用 latest,升级时你会失去节奏感,像在生产环境玩盲盒。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
services:
gitlab:
image: gitlab/gitlab-ee:<version>-ee.0
container_name: gitlab
restart: always
hostname: gitlab.example.com
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://gitlab.example.com:8929'
gitlab_rails['gitlab_shell_ssh_port'] = 2424
gitlab_rails['time_zone'] = 'Asia/Singapore'
ports:
- '8929:8929'
- '2424:22'
volumes:
- '/srv/gitlab/config:/etc/gitlab'
- '/srv/gitlab/logs:/var/log/gitlab'
- '/srv/gitlab/data:/var/opt/gitlab'
shm_size: '256m'

如果你希望 GitLab 直接接管标准端口:

1
2
3
4
ports:
- '80:80'
- '443:443'
- '22:22'

并设置:

1
external_url 'https://gitlab.example.com'

6.3 启动

1
2
cd /srv/gitlab
docker compose up -d

首次启动可能需要数分钟。查看日志:

1
docker logs -f gitlab

查看状态:

1
docker exec -it gitlab gitlab-ctl status

6.4 获取初始 root 密码

1
docker exec -it gitlab grep 'Password:' /etc/gitlab/initial_root_password

登录后请立即:

  1. 修改 root 密码。
  2. 修改 root 邮箱。
  3. 创建日常管理员账号。
  4. 尽量不要长期用 root 做日常操作。

6.5 Docker 方案的目录备份重点

Docker 方案一定要保护好:

1
2
3
/srv/gitlab/config/gitlab.rb
/srv/gitlab/config/gitlab-secrets.json
/srv/gitlab/data/backups/

gitlab-secrets.json 非常关键,它包含数据库加密相关密钥,丢了会导致 2FA、CI/CD variables、Runner 等出现严重问题。备份 GitLab,不备份 secrets,基本等于把保险柜备份了,把钥匙扔河里了。

7. 方案 B:Linux package / Omnibus 部署

生产单机更推荐 Linux package,也就是常说的 Omnibus GitLab。它把 GitLab Rails、PostgreSQL、Redis、Gitaly、Sidekiq、Puma、NGINX 等组件整合到一套包里,升级和管理体验更稳定。

以下以 Ubuntu 为例。

7.1 开启 SSH 和防火墙

1
2
3
4
5
6
7
8
sudo apt update
sudo apt install -y curl openssh-server ca-certificates tzdata perl
sudo systemctl enable --now ssh

sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

7.2 添加仓库

Enterprise Edition:

1
curl --location "https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.deb.sh" | sudo bash

Community Edition:

1
curl --location "https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh" | sudo bash

7.3 安装

Enterprise Edition:

1
sudo EXTERNAL_URL="https://gitlab.example.com" apt install gitlab-ee

Community Edition:

1
sudo EXTERNAL_URL="https://gitlab.example.com" apt install gitlab-ce

如果一开始没设置 EXTERNAL_URL,也可以后续编辑:

1
sudo vim /etc/gitlab/gitlab.rb

配置:

1
external_url "https://gitlab.example.com"

重新配置:

1
sudo gitlab-ctl reconfigure

查看状态:

1
sudo gitlab-ctl status

查看初始密码:

1
sudo cat /etc/gitlab/initial_root_password

8. HTTPS 与证书

如果 external_url 使用 https://,并且没有额外配置证书,GitLab Linux package 可以启用 Let’s Encrypt 集成。注意:Let’s Encrypt 的 HTTP 验证通常要求公网能够访问 80 和 443 标准端口;如果是纯内网、非标准端口、离线环境,就不要指望它自动签发。

内网 HTTPS 常见选择:

  1. 使用公司 CA 或自建 CA。
  2. 使用反向代理统一终止 TLS。
  3. 只通过 VPN 暴露 GitLab,内部使用受信任证书。

8.1 GitLab 直出 HTTPS

/etc/gitlab/gitlab.rb

1
2
external_url "https://gitlab.example.com"
letsencrypt['contact_emails'] = ['admin@example.com']

然后:

1
sudo gitlab-ctl reconfigure

8.2 反向代理模式

如果你已经有 NGINX、Caddy、Traefik 做统一入口,可以让外部代理处理 HTTPS,GitLab 内部监听 HTTP 端口。

典型思路:

1
2
3
external_url "https://gitlab.example.com"
nginx['listen_port'] = 8081
nginx['listen_https'] = false

然后由外部反向代理转发到 http://gitlab-internal:8081

注意:

  • external_url 仍然写用户访问的 HTTPS 地址。
  • 代理要正确传递 HostX-Forwarded-ProtoX-Forwarded-For
  • 上传大文件、Git LFS、Artifacts 时,要调整代理的 body size、timeout、buffering。

反向代理是 GitLab 私服里最容易“看似能访问,实际各种暗坑”的地方。能让 GitLab 直接接 443 就简单很多;要统一入口就必须认真测 clone、push、LFS、CI artifacts、Registry。

9. 初始化后的必要配置

登录后台后建议立刻做这些配置。

9.1 关闭或限制公开注册

路径:

1
Admin -> Settings -> General -> Sign-up restrictions

建议:

  • 内网私服:关闭公开注册。
  • 公司私服:开启管理员审批或限制邮箱域名。
  • 公网私服:必须关闭公开注册或启用严格审批。

9.2 配置 SMTP

没有 SMTP,用户无法正常收密码重置、通知、邀请、CI 失败提醒。

/etc/gitlab/gitlab.rb 示例:

1
2
3
4
5
6
7
8
9
10
11
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.example.com"
gitlab_rails['smtp_port'] = 587
gitlab_rails['smtp_user_name'] = "gitlab@example.com"
gitlab_rails['smtp_password'] = "CHANGE_ME"
gitlab_rails['smtp_domain'] = "example.com"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true

gitlab_rails['gitlab_email_from'] = 'gitlab@example.com'
gitlab_rails['gitlab_email_display_name'] = 'GitLab'

重新配置:

1
sudo gitlab-ctl reconfigure

Docker:

1
docker exec -it gitlab gitlab-ctl reconfigure

9.3 创建 Group 和权限模型

推荐结构:

1
2
3
4
5
6
7
8
9
10
company
├── platform
│ ├── gateway
│ ├── auth-service
│ └── infra-scripts
├── business
│ ├── finance-service
│ └── order-service
└── experiments
└── rag-lab

权限建议:

角色 建议用途
Owner 少数平台管理员,不给普通开发
Maintainer 项目负责人,可管理分支、MR、CI/CD
Developer 普通开发,可推分支、提 MR
Reporter 只读代码和 Issue
Guest 极低权限,按需使用

9.4 保护默认分支

建议:

  • main/master 禁止直接 push。
  • 必须通过 Merge Request 合并。
  • 开启至少 1 人 Review。
  • CI 成功后才允许合并。
  • 生产分支限制 Maintainer 合并。

10. GitLab Runner:CI/CD 的执行器

GitLab 本体只负责任务编排,真正执行 CI/CD Job 的是 GitLab Runner。

强烈建议:Runner 不要装在 GitLab 本机上。 官方也建议出于安全和性能原因,将 Runner 安装在独立机器上。原因很简单:CI Job 本质上是在跑用户提交的脚本,把它和代码平台放一台机器上,隔离边界会变得很脆。

10.1 Runner 类型

类型 说明 建议
Instance Runner 整个 GitLab 实例共享 平台统一 Runner
Group Runner 某个 Group 共享 团队级推荐
Project Runner 单项目专用 需要隔离时使用

10.2 安装 Runner

Ubuntu 示例:

1
2
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash
sudo apt install -y gitlab-runner

10.3 注册 Runner

在 GitLab UI 中创建 Runner,获取 glrt- 开头的 Runner authentication token,然后注册:

1
2
3
4
5
6
7
sudo gitlab-runner register \
--url "https://gitlab.example.com" \
--token "glrt-xxxxxxxxxxxxxxxx" \
--executor "docker" \
--docker-image "alpine:latest" \
--description "docker-runner-01" \
--tag-list "docker,linux"

查看:

1
2
sudo gitlab-runner list
sudo gitlab-runner verify

10.4 Runner 安全建议

  1. 不可信项目不要使用 Shell executor。
  2. Docker executor 不要随便开 privileged = true
  3. 不同安全等级的项目使用不同 Runner。
  4. Runner 机器不要保存生产密钥。
  5. CI/CD variables 要分环境、分权限、分 protected 状态。
  6. 给 Runner 打 tag,避免所有任务乱跑。

一个基础 .gitlab-ci.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
stages:
- test
- build

unit-test:
stage: test
image: maven:3.9-eclipse-temurin-21
script:
- mvn -B test
tags:
- docker

build-image:
stage: build
image: docker:27
services:
- docker:27-dind
script:
- echo "build image here"
tags:
- docker
rules:
- if: $CI_COMMIT_BRANCH == "main"

如果要使用 Docker-in-Docker,要额外关注 privileged、网络和镜像缓存。生产里更推荐 Kaniko、BuildKit、Buildah 或远程构建服务,别为了省事把 Runner 开成“root 体验卡”。

11. Container Registry

GitLab 可以作为 Docker 镜像仓库使用。每个项目都可以拥有自己的镜像空间。

11.1 启用 Registry

Linux package 示例:

1
registry_external_url 'https://registry.example.com'

重新配置:

1
sudo gitlab-ctl reconfigure

如果使用同域名加端口,也可能是:

1
registry_external_url 'https://gitlab.example.com:5050'

11.2 CI 推送镜像示例

1
2
3
4
5
6
7
8
9
build-image:
image: docker:27
services:
- docker:27-dind
stage: build
script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
- docker build -t "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA" .
- docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA"

11.3 Registry 运维注意点

  • 镜像增长很快,要配置清理策略。
  • 如果走对象存储,备份策略要单独考虑。
  • HTTPS 是默认推荐,不建议 HTTP Registry。
  • 反向代理时要测试 docker logindocker push、大镜像上传。

12. 备份:不是有 tar 就叫安全

GitLab 备份分两类:

  1. 应用数据备份:数据库、仓库、uploads、artifacts、LFS、packages 等。
  2. 配置与密钥备份gitlab.rbgitlab-secrets.json、证书、SSH host keys。

这两类必须一起备份。只备份应用数据不备份 secrets,恢复时可能会遇到 CI/CD variables 无法解密、2FA 用户无法登录、Runner 失效等问题。

12.1 Linux package 备份

应用备份:

1
sudo gitlab-backup create

配置备份:

1
sudo gitlab-ctl backup-etc

配置备份默认会生成到:

1
/etc/gitlab/config_backup/

建议把它复制到独立位置,并加密保存。

12.2 Docker 备份

应用备份:

1
docker exec -t gitlab gitlab-backup create

备份会写入容器内 /var/opt/gitlab/backups,也就是宿主机:

1
/srv/gitlab/data/backups

配置备份:

1
sudo tar -czf /backup/gitlab-config-$(date +%F).tar.gz -C /srv/gitlab config

12.3 设置备份保留时间

/etc/gitlab/gitlab.rb 或 Docker 的 GITLAB_OMNIBUS_CONFIG

1
2
# 7 天,单位秒
gitlab_rails['backup_keep_time'] = 604800

重新配置:

1
sudo gitlab-ctl reconfigure

Docker:

1
docker exec -it gitlab gitlab-ctl reconfigure

12.4 Cron 示例

Linux package:

1
sudo crontab -e -u root
1
2
15 02 * * * /opt/gitlab/bin/gitlab-backup create CRON=1
30 02 * * * /opt/gitlab/bin/gitlab-ctl backup-etc

Docker:

1
2
15 02 * * * docker exec -t gitlab gitlab-backup create CRON=1
30 02 * * * tar -czf /backup/gitlab-config-$(date +\%F).tar.gz -C /srv/gitlab config

12.5 备份必须测试恢复

最低要求:

  • 每月做一次恢复演练。
  • 恢复到独立测试机。
  • 校验登录、项目、MR、Wiki、Artifacts、LFS、Registry、CI variables。
  • 记录恢复步骤和耗时。

没测试过恢复的备份,只能叫“心理安慰文件”。

13. 恢复:版本、类型、secrets 都要匹配

GitLab 恢复有几个硬要求:

  1. 目标 GitLab 必须是可运行实例。
  2. 目标实例应是空实例或按官方要求清理。
  3. 备份只能恢复到完全相同版本和类型的 GitLab,例如 16.5.0-ee16.5.0-ee
  4. 必须恢复 gitlab-secrets.json
  5. 使用对象存储时,对象存储数据不是简单 tar 一把梭,需要单独规划。

13.1 Linux package 恢复简化流程

安装相同版本 GitLab 后:

1
2
sudo cp gitlab-secrets.json /etc/gitlab/gitlab-secrets.json
sudo gitlab-ctl reconfigure

放置备份文件:

1
2
sudo cp <backup-id>_gitlab_backup.tar /var/opt/gitlab/backups/
sudo chown git:git /var/opt/gitlab/backups/<backup-id>_gitlab_backup.tar

停止连接数据库的进程:

1
2
3
sudo gitlab-ctl stop puma
sudo gitlab-ctl stop sidekiq
sudo gitlab-ctl status

恢复:

1
sudo gitlab-backup restore BACKUP=<backup-id>

恢复后:

1
2
3
sudo gitlab-ctl start
sudo gitlab-rake gitlab:check SANITIZE=true
sudo gitlab-rake gitlab:doctor:secrets

13.2 Docker 恢复简化流程

确保镜像版本与备份一致,恢复 /srv/gitlab/config/gitlab-secrets.json 后:

1
docker compose up -d

把备份文件放到:

1
/srv/gitlab/data/backups/

进入容器恢复:

1
2
3
docker exec -it gitlab gitlab-backup restore BACKUP=<backup-id>
docker exec -it gitlab gitlab-rake gitlab:check SANITIZE=true
docker exec -it gitlab gitlab-rake gitlab:doctor:secrets

14. 升级策略

GitLab 升级不要图快,尤其不要跨多个大版本直接跳。正确姿势:

  1. 阅读目标版本升级说明。
  2. 确认当前版本到目标版本的升级路径。
  3. 备份应用数据和 /etc/gitlab/srv/gitlab/config
  4. 开维护窗口。
  5. 暂停 CI/CD Pipeline 和 Job。
  6. 先升级 GitLab Runner 到目标 GitLab 兼容版本。
  7. 升级 GitLab 本体。
  8. 执行健康检查。
  9. 观察日志和核心功能。
  10. 再恢复 CI/CD。

14.1 Docker Compose 升级

修改 docker-compose.yml 中镜像版本:

1
image: gitlab/gitlab-ee:<new-version>-ee.0

执行:

1
2
docker compose pull
docker compose up -d

查看日志:

1
docker logs -f gitlab

健康检查:

1
docker exec -it gitlab gitlab-rake gitlab:check SANITIZE=true

14.2 Linux package 升级

查看可用版本:

1
apt-cache madison gitlab-ee

安装指定版本:

1
sudo apt install gitlab-ee=<version>

或升级到仓库中的目标版本:

1
2
sudo apt update
sudo apt install gitlab-ee

升级后:

1
2
sudo gitlab-rake gitlab:check SANITIZE=true
sudo gitlab-ctl status

14.3 升级的红线

  • 不要用 latest
  • 不要没备份就升级。
  • 不要不看升级路径直接跨版本。
  • 不要 GitLab 本体升级了,Runner 永远不升级。
  • 不要在业务高峰期升级。
  • 不要升级后不做健康检查。

15. 监控与日常排障

15.1 基础状态命令

Linux package:

1
2
3
sudo gitlab-ctl status
sudo gitlab-ctl tail
sudo gitlab-rake gitlab:check SANITIZE=true

Docker:

1
2
3
docker exec -it gitlab gitlab-ctl status
docker exec -it gitlab gitlab-ctl tail
docker exec -it gitlab gitlab-rake gitlab:check SANITIZE=true

15.2 常看日志

1
2
3
4
5
6
7
/var/log/gitlab/gitlab-rails/production.log
/var/log/gitlab/gitlab-rails/application.log
/var/log/gitlab/nginx/gitlab_access.log
/var/log/gitlab/nginx/gitlab_error.log
/var/log/gitlab/sidekiq/current
/var/log/gitlab/gitaly/current
/var/log/gitlab/postgresql/current

Docker 对应宿主机:

1
/srv/gitlab/logs/

15.3 Prometheus

GitLab Linux package 自带 Prometheus 及多个 exporter,默认监听本机 localhost:9090。不要随便把 Prometheus 暴露到公网,因为 exporter 指标通常不做用户认证,暴露出去既不安全,也容易泄露内部结构。

建议监控:

  • CPU、内存、磁盘空间、磁盘 IO。
  • PostgreSQL 连接数、慢查询、数据库大小。
  • Sidekiq 队列长度。
  • Gitaly 请求延迟。
  • 5xx 错误率。
  • Runner 在线状态和 Job 排队时间。
  • 备份是否成功、备份文件大小是否异常。

16. 安全基线

下面是一套适合内网/公网 GitLab 私服的安全基线。

16.1 账号安全

  • 关闭公开注册,或开启管理员审批。
  • 管理员账号启用 2FA。
  • 核心 Group 强制 2FA。
  • 开启 Admin Mode,让管理员执行敏感操作时再次确认身份。
  • 禁止多人共用 root。
  • 定期清理离职用户、长期不活跃用户和过期 Token。

16.2 网络安全

  • 优先 HTTPS。
  • 公网访问优先走 VPN 或零信任网关。
  • 如果必须公网开放,只开放 443 和 Git SSH 端口。
  • 管理后台不要暴露在不受控网络中。
  • 配置反向代理真实 IP,避免所有请求都显示成代理 IP,导致限流和审计失真。

16.3 CI/CD 安全

  • Runner 独立部署。
  • 不可信项目不要用 Shell executor。
  • 不要默认开启 Docker privileged。
  • Protected variables 只给 protected branch/tag 使用。
  • 生产发布使用独立 Runner 或受限环境。
  • CI 日志不要打印密钥。

16.4 数据安全

  • 应用备份和配置备份分开保存。
  • gitlab-secrets.json 加密保存。
  • 备份至少保留一份异地副本。
  • 每月恢复演练。
  • 备份文件不要和 GitLab 主机放在同一块“会一起坏”的磁盘上。

16.5 访问限制与 Rate Limit

GitLab 有多种可配置或不可配置的 Rate Limit,用来降低滥用和 DoS 风险。公网实例建议重点关注:

  • 登录失败限制。
  • 注册接口限制。
  • API 请求限制。
  • Webhook 测试限制。
  • 大文件 blob/file API 访问限制。
  • Repository archive 下载限制。

Rate Limit 不是银弹,但能避免脚本小子把你的 GitLab 当健身器械猛撸。

17. 常见坑

17.1 external_url 写错

表现:

  • 页面能访问,但 clone 地址不对。
  • Webhook 回调不对。
  • CI/CD 中 $CI_SERVER_URL 不对。
  • 登录跳转异常。

处理:

1
2
sudo vim /etc/gitlab/gitlab.rb
sudo gitlab-ctl reconfigure

Docker:修改 GITLAB_OMNIBUS_CONFIG 后重启容器。

17.2 SSH 端口映射了,但 GitLab 页面没变

如果你映射了:

1
2
ports:
- '2424:22'

也必须配置:

1
gitlab_rails['gitlab_shell_ssh_port'] = 2424

否则页面仍然显示默认 22。

17.3 只备份了 /var/opt/gitlab/backups

这不够。还要备份:

1
2
3
4
/etc/gitlab/gitlab.rb
/etc/gitlab/gitlab-secrets.json
TLS certificates
SSH host keys

Docker 对应:

1
/srv/gitlab/config/

17.4 磁盘被 artifacts 或 registry 打满

处理方向:

  • 设置 artifacts 过期时间。
  • 设置 job log/artifacts 保留策略。
  • 配置 Container Registry cleanup policy。
  • 监控磁盘空间。
  • 大团队考虑对象存储。

17.5 Runner 长期 pending

排查:

  1. Runner 是否在线。
  2. Job tag 是否和 Runner tag 匹配。
  3. Runner 是否 locked 到某项目。
  4. Runner executor 是否能拉镜像。
  5. Runner 网络是否能访问 GitLab。
  6. 并发数是否太低。

17.6 反向代理后 clone/push 大文件失败

检查:

  • client_max_body_size
  • proxy timeout。
  • request buffering。
  • Git LFS 路径。
  • Registry 上传路径。
  • X-Forwarded-Proto 是否正确。

18. 推荐落地架构

18.1 小团队内网版

flowchart LR
    Dev[开发者电脑] -->|HTTPS/SSH| DNS[内网 DNS]
    DNS --> GL[GitLab Docker Compose / Omnibus]
    GL --> Disk[(SSD/NVMe 数据盘)]
    GL --> Backup[(异机/异盘备份)]
    Runner[GitLab Runner 独立机器] -->|拉取 Job| GL
    Runner --> Docker[Docker/BuildKit]

特点:

  • GitLab 单机。
  • Runner 独立。
  • 内网 DNS。
  • 定时备份到另一台机器。
  • 适合 5-30 人团队或家庭实验室。

18.2 公网访问增强版

flowchart LR
    User[外部用户] --> WAF[反向代理 / WAF / VPN]
    WAF --> GL[GitLab]
    GL --> PG[(内置或外部 PostgreSQL)]
    GL --> Redis[(内置或外部 Redis)]
    GL --> Backup[(异地备份)]
    Runner[Runner 池] --> GL
    GL --> Registry[(Registry / 对象存储)]

特点:

  • 公网只开放必要入口。
  • HTTPS 强制。
  • 关闭公开注册。
  • 管理员 2FA。
  • 备份异地化。
  • Runner 池与 GitLab 隔离。

19. Day-2 运维清单

每天:

  • 看备份是否成功。
  • 看磁盘剩余空间。
  • 看 GitLab 服务状态。
  • 看 Runner 是否在线。

每周:

  • 检查 GitLab 安全更新。
  • 清理异常失败的 Pipeline。
  • 检查大仓库、Artifacts、Registry 增长。
  • 审查新增管理员和 Token。

每月:

  • 做一次恢复演练。
  • 升级测试环境。
  • 检查证书过期时间。
  • 清理离职用户和无用项目。
  • 复盘 CI/CD 耗时和 Runner 负载。

每季度:

  • 审查权限模型。
  • 评估是否需要拆分 Runner。
  • 评估是否需要对象存储。
  • 评估是否需要从单机走向参考架构。

20. 我的推荐配置

如果你是个人或小团队,我建议这样起步:

1
2
3
4
5
6
7
8
9
10
部署方式:Docker Compose 或 Omnibus
CPU:4 核
内存:8GB 起,16GB 更舒服
磁盘:200GB SSD/NVMe 起
访问:内网 DNS + VPN 远程访问
HTTPS:内网 CA 或反向代理统一证书
Runner:独立机器 Docker executor
备份:每天应用备份 + 配置备份 + 异机保存
升级:每月跟进小版本,先测试再生产
安全:关闭公开注册 + 管理员 2FA + 保护分支 + Runner 隔离

如果是公司生产:

1
2
3
4
5
6
部署方式:优先 Omnibus,规模上来后参考官方 Reference Architecture
备份:必须有恢复演练
监控:Prometheus + Grafana + 告警
Runner:按团队/环境隔离
Registry:配置清理策略或对象存储
权限:Group 分层 + 最小权限 + 定期审计

21. 总结

GitLab 私服的核心不是“安装”,而是“持续运行”。安装只占 20%,剩下 80% 是:

  • 域名和 HTTPS 是否规划清楚。
  • Runner 是否隔离。
  • 备份是否包含 secrets。
  • 恢复是否演练过。
  • 升级是否有路径。
  • 权限和注册是否收紧。
  • 磁盘和监控是否跟得上。

如果你只想快速有个 Git 仓库,轻量工具更省心;如果你想要代码、CI/CD、镜像、权限、制品、协作的一体化平台,GitLab 私服值得投入。记住一句话:GitLab 可以自托管,但不要自欺欺人地“无运维”。


参考资料


GitLab 私服从 0 到 1:部署、Runner、备份、升级与安全基线
https://allendericdalexander.github.io/2026/06/21/devops/infra/gitlab-self-managed-blog/
作者
AtLuoFu
发布于
2026年6月21日
许可协议