GitLab 容器化部署与配置完全指南

GitLab 容器化部署与配置完全指南

Someone Lv5

GitLab 是目前最流行的自托管 DevOps 平台之一,提供代码托管、CI/CD、容器注册表、项目管理等一站式服务。本文将详细介绍如何在 Ubuntu 22.04 上使用 Docker Compose 部署 GitLab 社区版,并进行生产级的配置优化。

1. 部署方案选择

在部署 GitLab 之前,需要根据团队规模和资源情况选择合适的方案。

方案适用场景优点缺点
Omnibus 一键包单机部署、小团队安装简单、开箱即用升级复杂、隔离性差
Docker Compose中小团队、容器化环境部署快、版本管理清晰、易于备份需先部署 Docker
Kubernetes Helm大型团队、高可用场景弹性伸缩、滚动升级运维门槛高、资源消耗大

本文采用 Docker Compose 方案,兼顾部署效率与可维护性。

2. 前提条件

2.1 硬件要求

GitLab 对系统资源有一定要求,建议配置如下:

用户数CPU内存磁盘
1-10 人2 核4 GB50 GB SSD
10-50 人4 核8 GB100 GB SSD
50-200 人8 核16 GB200 GB SSD

2.2 软件环境

  • Ubuntu 22.04 LTS
  • Docker Engine 24.0+
  • Docker Compose V2(推荐)或 V1

2.3 安装 Docker

如果尚未安装 Docker,执行以下命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 卸载旧版本
sudo apt remove docker docker-engine docker.io containerd runc

# 安装依赖
sudo apt update
sudo apt install -y ca-certificates curl gnupg lsb-release

# 添加 Docker 官方 GPG 密钥和源
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

echo \
"deb [arch=$(dpkg --print-architecture) \
signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# 安装 Docker Engine 和 Compose
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

# 将当前用户加入 docker 组(免 sudo 执行)
sudo usermod -aG docker $USER
newgrp docker

3. 部署 GitLab

3.1 创建目录结构

1
2
mkdir -p /opt/gitlab/{config,logs,data}
cd /opt/gitlab

3.2 编写 docker-compose.yml

创建 /opt/gitlab/docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
version: '3.8'

services:
gitlab:
image: gitlab/gitlab-ce:17.2.0-ce.0
container_name: gitlab
restart: always
hostname: 'gitlab.example.com' # 修改为实际域名
environment:
GITLAB_OMNIBUS_CONFIG: |
# 外部访问 URL
external_url 'https://gitlab.example.com'

# 时区
gitlab_rails['time_zone'] = 'Asia/Shanghai'

# SMTP 邮件配置(以 QQ 邮箱为例)
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = 'smtp.qq.com'
gitlab_rails['smtp_port'] = 465
gitlab_rails['smtp_user_name'] = 'your-email@qq.com'
gitlab_rails['smtp_password'] = 'your-smtp-auth-code'
gitlab_rails['smtp_domain'] = 'qq.com'
gitlab_rails['smtp_authentication'] = 'login'
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = true
gitlab_rails['gitlab_email_from'] = 'your-email@qq.com'
gitlab_rails['gitlab_email_reply_to'] = 'your-email@qq.com'

# 备份配置
gitlab_rails['backup_keep_time'] = 604800 # 保留7天(秒)
gitlab_rails['backup_path'] = '/var/opt/gitlab/backups'

# 限制注册功能
gitlab_rails['gitlab_signup_enabled'] = false # 关闭开放注册
gitlab_rails['gitlab_signin_oauth_auto_ldap_sync'] = false

# SSH 端口
gitlab_rails['gitlab_shell_ssh_port'] = 2222

# Gitaly 配置
gitaly['configuration'] = {
storage: [
{
name: 'default',
path: '/var/opt/gitlab/git-data/repositories',
}
]
}

# Puma 配置(建议 = CPU 核数 + 1)
puma['worker_processes'] = 3
puma['min_threads'] = 4
puma['max_threads'] = 16

# Sidekiq 并发
sidekiq['concurrency'] = 10
ports:
- '2222:22' # SSH(映射到主机非标准端口)
- '80:80' # HTTP
- '443:443' # HTTPS
volumes:
- /opt/gitlab/config:/etc/gitlab
- /opt/gitlab/logs:/var/log/gitlab
- /opt/gitlab/data:/var/opt/gitlab
shm_size: '256m' # 增加共享内存,提升 Puma 性能
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/-/health"]
interval: 30s
timeout: 10s
retries: 5
start_period: 120s

3.3 启动 GitLab

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

首次启动需要 3-5 分钟完成初始化配置,可以通过以下命令观察启动日志:

1
docker compose logs -f gitlab

当看到类似 GitLab is ready! 的日志时,服务即启动完成。

3.4 获取初始管理员密码

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

默认用户名为 root,请首次登录后立即修改密码。

4. Nginx 反向代理与 HTTPS

在生产环境中,建议使用独立 Nginx 作为反向代理终止 HTTPS,而不是直接暴露 GitLab 的 80/443 端口。

4.1 安装 Nginx 和 Certbot

1
sudo apt install -y nginx certbot python3-certbot-nginx

4.2 配置 Nginx 反向代理

创建 /etc/nginx/sites-available/gitlab

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
upstream gitlab {
server 127.0.0.1:80;
keepalive 32;
}

server {
listen 80;
server_name gitlab.example.com;
return 301 https://$server_name$request_uri;
}

server {
listen 443 ssl http2;
server_name gitlab.example.com;

ssl_certificate /etc/letsencrypt/live/gitlab.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/gitlab.example.com/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;

# 现代 TLS 配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;

# HSTS
add_header Strict-Transport-Security "max-age=63072000" always;

# GitLab 反向代理
location / {
proxy_pass http://gitlab;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Ssl on;
proxy_redirect off;
proxy_buffering off;

# WebSocket 支持
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

# 超时设置(GitLab 一些操作耗时较长)
proxy_read_timeout 300s;
proxy_connect_timeout 75s;
}
}

4.3 修改 GitLab external_url

配置 Nginx 后,需要更新 GitLab 的 external_url

1
2
3
4
5
6
7
8
9
10
# 在 docker-compose.yml 中修改环境变量
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'https://gitlab.example.com'
nginx['listen_port'] = 80
nginx['listen_https'] = false
nginx['proxy_set_headers'] = {
'X-Forwarded-Proto' => 'https',
'X-Forwarded-Ssl' => 'on'
}

然后重启 GitLab:

1
2
3
cd /opt/gitlab
docker compose down
docker compose up -d

5. 备份与恢复

5.1 手动备份

1
2
3
4
5
# 创建备份
docker exec -it gitlab gitlab-backup create

# 备份配置文件(单独备份,恢复时重要)
tar -czf /opt/gitlab-backups/gitlab-config-$(date +%Y%m%d).tar.gz /opt/gitlab/config

备份文件默认存储在 /opt/gitlab/data/backups/ 目录下。

5.2 定时自动备份

创建备份脚本 /opt/gitlab/backup.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/bin/bash
# GitLab 自动备份脚本

BACKUP_DIR="/opt/gitlab-backups"
RETENTION_DAYS=7
DATE=$(date +%Y%m%d_%H%M%S)
LOG_FILE="/var/log/gitlab-backup.log"

# 设置日志
echo "[$(date)] 开始 GitLab 备份" >> "$LOG_FILE"

# 创建 GitLab 数据备份
docker exec gitlab gitlab-backup create STRATEGY=copy >> "$LOG_FILE" 2>&1
if [ $? -ne 0 ]; then
echo "[$(date)] ❌ 备份失败!" >> "$LOG_FILE"
exit 1
fi

# 备份配置文件
mkdir -p "$BACKUP_DIR"
tar -czf "$BACKUP_DIR/gitlab-config-$DATE.tar.gz" -C /opt/gitlab config >> "$LOG_FILE" 2>&1

# 清理过期备份
find "$BACKUP_DIR" -name "gitlab-config-*.tar.gz" -mtime +$RETENTION_DAYS -delete
find /opt/gitlab/data/backups -name "*.tar" -mtime +$RETENTION_DAYS -delete

echo "[$(date)] ✅ GitLab 备份完成" >> "$LOG_FILE"

添加执行权限并设置定时任务:

1
2
3
4
chmod +x /opt/gitlab/backup.sh

# 添加到 crontab(每天凌晨3点执行)
echo "0 3 * * * /opt/gitlab/backup.sh" | sudo crontab -

5.3 恢复备份

1
2
3
4
5
6
7
8
9
10
11
12
# 停止相关服务
docker exec gitlab gitlab-ctl stop puma
docker exec gitlab gitlab-ctl stop sidekiq

# 恢复数据库(确保备份文件在 data/backups 目录下)
docker exec gitlab gitlab-backup restore BACKUP=1712345678_2026_06_17_17.2.0

# 重启 GitLab
docker exec gitlab gitlab-ctl restart

# 恢复后重新配置
docker exec gitlab gitlab-ctl reconfigure

注意:恢复操作需要版本号完全匹配,建议在恢复前记录当前运行版本。

6. GitLab Runner 注册

GitLab Runner 是执行 CI/CD 任务的组件,以 Docker 方式部署方便灵活。

6.1 部署 Runner

1
2
3
4
5
6
7
8
# 创建 Runner 目录
mkdir -p /opt/gitlab-runner/{config,data}

# 启动 Runner 容器
docker run -d --name gitlab-runner --restart always \
-v /opt/gitlab-runner/config:/etc/gitlab-runner \
-v /var/run/docker.sock:/var/run/docker.sock \
gitlab/gitlab-runner:latest

6.2 注册 Runner

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 交互式注册
docker exec -it gitlab-runner gitlab-runner register

# 或使用非交互方式(填入实际 URL 和 Token)
docker exec -it gitlab-runner gitlab-runner register \
--non-interactive \
--url "https://gitlab.example.com" \
--registration-token "YOUR_REGISTRATION_TOKEN" \
--executor "docker" \
--docker-image alpine:latest \
--docker-volumes /var/run/docker.sock:/var/run/docker.sock \
--description "docker-runner" \
--tag-list "docker,linux" \
--run-untagged="true" \
--locked="false"

Runner Token 可以在 GitLab 管理界面获取:Settings → CI/CD → Runners → Expand → Specific runners

6.3 Runner 配置优化

编辑 /opt/gitlab-runner/config/config.toml,对 Runner 配置进行调优:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
concurrent = 4

[[runners]]
name = "docker-runner"
url = "https://gitlab.example.com"
token = "YOUR_TOKEN"
executor = "docker"
[runners.docker]
image = "alpine:latest"
privileged = false # 安全考虑,非必要不开启
disable_cache = false
volumes = ["/cache"]
shm_size = 256m
pull_policy = "if-not-present" # 优先使用本地镜像
oom_kill_disable = false
memory_limit = "2g" # 限制容器内存
cpus = "2" # 限制 CPU 核数
helper_image = "gitlab/gitlab-runner-helper:x86_64-latest"
[runners.cache]
Type = "s3"
Path = "gitlab-runner-cache"
Shared = true

7. GitLab CI/CD 基础配置

7.1 基础 .gitlab-ci.yml 模板

在项目根目录创建 .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
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
stages:
- test
- build
- deploy

variables:
DOCKER_IMAGE_TAG: $CI_COMMIT_SHORT_SHA

# 测试阶段
test:
stage: test
image: node:20-alpine
script:
- npm install
- npm run lint
- npm test
only:
- main
- merge_requests

# 构建阶段
build:
stage: build
image: docker:24
services:
- docker:24-dind
script:
- docker build -t registry.example.com/myapp:$DOCKER_IMAGE_TAG .
- docker push registry.example.com/myapp:$DOCKER_IMAGE_TAG
only:
- main

# 部署阶段
deploy:
stage: deploy
image: alpine:latest
before_script:
- apk add --no-cache openssh-client
script:
- scp -o StrictHostKeyChecking=no docker-compose.yml deploy@server:/opt/app/
- ssh deploy@server "cd /opt/app && docker compose pull && docker compose up -d"
only:
- main
when: manual # 手动触发部署

7.2 注册表配置(可选)

如需使用 GitLab 内置的 Container Registry:

1
2
3
4
5
6
7
8
9
10
# 在 docker-compose.yml 中添加
environment:
GITLAB_OMNIBUS_CONFIG: |
# 启用 Container Registry
registry_external_url 'https://registry.example.com'
registry_nginx['listen_port'] = 5050
registry_nginx['listen_https'] = false
# 添加端口映射
ports:
- '5050:5050'

8. 性能优化

8.1 GitLab 内核参数调优

1
2
3
4
5
6
7
8
# 增加文件描述符限制
echo "fs.file-max = 100000" | sudo tee -a /etc/sysctl.conf

# 扩大连接跟踪表
echo "net.netfilter.nf_conntrack_max = 262144" | sudo tee -a /etc/sysctl.conf

# 应用
sudo sysctl -p

8.2 Docker 资源限制

1
2
3
4
5
6
7
8
9
10
11
# 在 docker-compose.yml 中添加资源限制
services:
gitlab:
deploy:
resources:
limits:
cpus: '4'
memory: 8G
reservations:
cpus: '2'
memory: 4G

8.3 数据库优化

GitLab 使用 PostgreSQL 作为数据库,可以单独优化:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 在 docker-compose.yml 中添加独立 PostgreSQL
services:
gitlab:
# ... 原有配置 ...
environment:
GITLAB_OMNIBUS_CONFIG: |
# 使用外部数据库
postgresql['enable'] = false
gitlab_rails['db_adapter'] = 'postgresql'
gitlab_rails['db_username'] = 'gitlab'
gitlab_rails['db_password'] = 'secure_password'
gitlab_rails['db_host'] = 'postgresql'
gitlab_rails['db_port'] = 5432

postgresql:
image: postgres:16-alpine
container_name: gitlab-postgresql
restart: always
environment:
POSTGRES_USER: gitlab
POSTGRES_PASSWORD: secure_password
POSTGRES_DB: gitlabhq_production
volumes:
- /opt/gitlab/postgresql:/var/lib/postgresql/data
deploy:
resources:
limits:
memory: 2G

9. 安全加固

9.1 防火墙配置

1
2
3
4
5
6
sudo ufw allow 22/tcp       # SSH
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
sudo ufw allow 2222/tcp # GitLab SSH(自定义端口)
sudo ufw deny 5050 # Container Registry 仅内网访问
sudo ufw enable

9.2 安全配置清单

配置项建议值说明
开放注册关闭防止恶意注册
密码复杂度最低12位,含大小写+数字+特殊字符GitLab 默认已启用
2FA 强制管理员强制启用Settings → General → Sign-in restrictions
Session 超时12 小时Settings → General → Session duration
IP 白名单仅允许内网访问管理面板可通过 Nginx 限制
Runner 权限非 privileged 模式防止容器逃逸
HTTPS 强制启用Nginx 重写所有 HTTP 到 HTTPS
数据加密AES-256备份文件加密存储

9.3 定期更新

GitLab 社区版每月 22 日左右发布新版本,建议定期更新:

1
2
3
4
5
6
7
# 查看当前版本
docker exec gitlab cat /opt/gitlab/embedded/service/gitlab-rails/VERSION

# 更新(修改 docker-compose.yml 中的镜像标签后)
cd /opt/gitlab
docker compose pull
docker compose up -d

10. 常见问题排查

问题可能原因解决方法
502 Bad GatewayPuma/Sidekiq 未完全启动等待 2-3 分钟或检查日志 docker compose logs gitlab
SSH 连接被拒绝SSH 端口映射冲突确认主机 2222 端口未被占用,ss -tlnp | grep 2222
邮件发送失败SMTP 配置错误检查 SMTP 地址、端口、认证码,测试 docker exec gitlab gitlab-rails console
磁盘空间不足备份文件未清理docker exec gitlab du -sh /var/opt/gitlab/backups,清理过期备份
Runner 无法连接注册 Token 过期或网络问题重新注册 Runner,确认 --url 参数正确
容器频繁重启系统资源不足docker stats 查看资源使用,增加主机内存
API 返回 413Nginx 上传大小限制在 Nginx 配置中添加 client_max_body_size 0;
Git push 超时Nginx proxy_read_timeout 不足增加超时时间至 600s

11. 总结

本文详细介绍了在 Ubuntu 22.04 上使用 Docker Compose 部署 GitLab 社区版的完整流程,涵盖:

  • Docker 环境准备与 GitLab 容器化部署
  • Nginx 反向代理与 HTTPS 配置
  • 自动备份与恢复方案
  • GitLab Runner 注册与 CI/CD 基础配置
  • 性能优化与安全加固
  • 常见问题排查

GitLab 是一个非常成熟的 DevOps 平台,通过容器化部署可以极大降低运维复杂度。建议在生产环境中配合独立的 PostgreSQL 和 Redis 实例以提升性能和可用性,同时定期检查安全配置和版本更新。


本文由AI辅助生成,内容仅供参考

  • 标题: GitLab 容器化部署与配置完全指南
  • 作者: Someone
  • 创建于 : 2026-06-17 00:43:00
  • 更新于 : 2026-06-18 08:39:57
  • 链接: https://demo-blog.qusite.cn/2026-06-17-gitlab-deployment-guide/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。