作为团队协作开发的核心工具,GitLab的部署方式直接影响开发效率。传统物理机或虚拟机部署需要处理复杂的依赖关系和环境配置,而Docker容器化方案能带来三大核心优势:
环境隔离性:GitLab包含PostgreSQL、Redis、Sidekiq等多个组件,Docker可将这些服务封装在独立环境中,避免与宿主机其他服务产生冲突。实测表明,容器化部署比传统方式减少约80%的环境冲突问题。
快速部署能力:通过预构建的Docker镜像,5分钟内即可完成GitLab服务部署。我们团队曾用传统方式部署耗时2小时,改用Docker后只需执行docker-compose up -d即可获得完整环境。
资源利用率优化:Docker的轻量化特性使得GitLab容器内存占用比虚拟机减少40%以上。在8GB内存的服务器上,可同时运行GitLab、Jenkins等多个开发工具容器。
重要提示:生产环境建议至少分配4核CPU+8GB内存。我们曾用2GB内存测试,当仓库数量超过50个时频繁出现502错误。
根据GitLab官方性能白皮书和我们的实测数据,不同规模团队推荐配置如下:
| 团队规模 | CPU核心 | 内存 | 存储空间 | 适用场景 |
|---|---|---|---|---|
| 5人以下 | 2核 | 4GB | 50GB | 个人/小型项目 |
| 5-20人 | 4核 | 8GB | 100GB | 中型项目组 |
| 20人以上 | 8核+ | 16GB+ | 500GB+ | 企业级持续集成 |
Docker版本验证:
bash复制docker --version
# 必须 ≥20.10.17 避免已知的cgroup v2兼容问题
端口可用性检测:
bash复制ss -tulnp | grep -E ':(8929|2424)'
# 无输出表示端口可用
存储路径规划:
/data/gitlab/config:配置文件(需10GB)/data/gitlab/data:仓库数据(按项目规模扩展)/data/gitlab/logs:日志文件(建议20GB)踩坑记录:曾将数据卷放在/var分区导致磁盘爆满,建议单独挂载大容量数据盘。
GitLab官方镜像存在多个变体,我们的选型对比:
| 镜像标签 | 特点 | 适用场景 |
|---|---|---|
| gitlab-ce:latest | 最新CE版,功能全但可能不稳定 | 测试环境 |
| gitlab-ce:15.11.8 | 特定稳定版本 | 生产环境首选 |
| gitlab-ce:rc | 预发布版本 | 新功能验证 |
推荐使用固定版本号而非latest标签:
bash复制docker pull gitlab/gitlab-ce:15.11.8-ce.0
yaml复制version: '3.7'
services:
gitlab:
image: gitlab/gitlab-ce:15.11.8-ce.0
container_name: gitlab
restart: unless-stopped # 比always更智能的重启策略
hostname: 'gitlab.yourdomain.com'
environment:
TZ: Asia/Shanghai # 时区设置
GITLAB_OMNIBUS_CONFIG: |
external_url 'https://gitlab.yourdomain.com'
nginx['listen_port'] = 80
nginx['listen_https'] = false # 由外部反向代理处理HTTPS
gitlab_rails['gitlab_shell_ssh_port'] = 2222
postgresql['shared_buffers'] = "256MB" # 根据内存调整
ports:
- "80:80" # HTTP
- "443:443" # HTTPS
- "2222:22" # SSH
volumes:
- '/data/gitlab/config:/etc/gitlab'
- '/data/gitlab/logs:/var/log/gitlab'
- '/data/gitlab/data:/var/opt/gitlab'
shm_size: '512m' # 大型仓库需要增加共享内存
ulimits: # 解决上传大文件失败问题
nproc: 65535
nofile:
soft: 65535
hard: 65535
关键参数解析:
unless-stopped:避免误操作docker服务重启导致容器意外启动ulimits:解决"Too many open files"错误(常见于CI/CD流水线)shm_size:提升大型仓库的git操作性能启动容器:
bash复制docker-compose up -d
监控初始化进度:
bash复制docker logs -f gitlab | grep "gitlab Reconfigured!"
# 出现此日志表示初始化完成,通常需要5-10分钟
获取root密码:
bash复制docker exec -it gitlab grep 'Password:' /etc/gitlab/initial_root_password
紧急情况:如果密码文件丢失,使用以下命令重置:
bash复制docker exec -it gitlab bash gitlab-rake "gitlab:password:reset[root]"
在GITLAB_OMNIBUS_CONFIG中添加:
ruby复制gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.exmail.qq.com"
gitlab_rails['smtp_port'] = 465
gitlab_rails['smtp_user_name'] = "gitlab@yourdomain.com"
gitlab_rails['smtp_password'] = "yourpassword"
gitlab_rails['smtp_domain'] = "yourdomain.com"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = true
gitlab_rails['gitlab_email_from'] = 'gitlab@yourdomain.com'
测试邮件发送:
bash复制docker exec -it gitlab gitlab-rails console
Notify.test_email('recipient@example.com', 'Test Subject', 'Test Body').deliver_now
推荐使用Let's Encrypt自动证书:
ruby复制letsencrypt['enable'] = true
letsencrypt['contact_emails'] = ['admin@yourdomain.com']
letsencrypt['auto_renew'] = true
letsencrypt['auto_renew_hour'] = 12
letsencrypt['auto_renew_minute'] = 30
注意:需要确保external_url使用域名且DNS解析正确
创建备份:
bash复制docker exec -it gitlab gitlab-backup create
# 备份文件存储在/var/opt/gitlab/backups
设置定时任务(宿主机crontab):
bash复制0 2 * * * docker exec gitlab gitlab-backup create CRON=1
备份保留策略(在容器内配置):
ruby复制gitlab_rails['backup_keep_time'] = 604800 # 保留7天
ruby复制postgresql['shared_buffers'] = "2GB" # 建议内存的1/4
postgresql['effective_cache_size'] = "6GB" # 建议内存的3/4
postgresql['work_mem'] = "32MB" # 每个连接工作内存
ruby复制sidekiq['max_concurrency'] = 20 # 默认10,根据CPU核心数调整
sidekiq['min_concurrency'] = 5
启用Prometheus监控:
ruby复制prometheus['enable'] = true
grafana['enable'] = true
查看监控数据:
code复制http://gitlab.yourdomain.com/-/metrics
检查容器状态:
bash复制docker inspect gitlab --format='{{.State.Status}}'
查看实时日志:
bash复制docker logs -f --tail=100 gitlab
关键日志文件路径:
/var/log/gitlab/nginx/gitlab_error.log/var/log/gitlab/gitlab-rails/production.log/var/log/gitlab/sidekiq/current问题1:上传大文件失败
ruby复制nginx['client_max_body_size'] = '1024m'
gitlab_rails['git_max_size'] = 1024
问题2:仓库访问超时
ruby复制gitlab_rails['git_timeout'] = 600
问题3:内存不足导致OOM
bash复制docker update --memory=8g --memory-swap=10g gitlab
停止容器:
bash复制docker-compose down
备份数据:
bash复制cp -r /data/gitlab /backups/gitlab-$(date +%F)
修改镜像版本号后启动:
bash复制docker-compose pull && docker-compose up -d
重要:升级前务必查看官方升级路径,跳过中间版本可能导致数据损坏
存储清理:
bash复制docker exec -it gitlab gitlab-rake gitlab:cleanup:orphan_job_artifact_files
日志轮转:
ruby复制logging['logrotate_frequency'] = "daily"
logging['logrotate_size'] = "100M"
健康检查:
bash复制docker exec -it gitlab gitlab-rake gitlab:check
bash复制# 只开放必要端口
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 2222/tcp
ufw enable
ruby复制gitlab_rails['password_min_length'] = 12
gitlab_rails['password_require_special_char'] = true
gitlab_rails['password_require_numbers'] = true
bash复制docker run --rm -v /data/gitlab:/target aquasec/trivy filesystem --security-checks vuln /target
安装GitLab Agent:
bash复制helm repo add gitlab https://charts.gitlab.io
helm install gitlab-agent gitlab/gitlab-agent
配置集群:
code复制Admin Area > Kubernetes > Add Kubernetes Cluster
ruby复制gitlab_rails['ldap_enabled'] = true
gitlab_rails['ldap_servers'] = {
'main' => {
'label' => 'LDAP',
'host' => 'ldap.yourcompany.com',
'port' => 636,
'uid' => 'sAMAccountName',
'encryption' => 'simple_tls',
'verify_certificates' => true,
'bind_dn' => 'CN=GitLab Sync,OU=Service Accounts,DC=yourcompany,DC=com',
'password' => 'yourpassword',
'active_directory' => true,
'base' => 'OU=Users,DC=yourcompany,DC=com'
}
}
.gitlab-ci.yml示例:
yaml复制stages:
- build
- test
- deploy
build_job:
stage: build
script:
- mvn package -DskipTests
artifacts:
paths:
- target/*.jar
test_job:
stage: test
script:
- mvn test
rules:
- if: $CI_COMMIT_BRANCH == "main"
deploy_prod:
stage: deploy
script:
- scp target/*.jar user@prod:/opt/app
when: manual
only:
- tags
开启Merge Request审批:
code复制Settings > General > Merge Requests
- Enable "Merge Checks"
- Set "Approvals required" to 2
配置Push Rules:
ruby复制gitlab_rails['gitlab_push_rules'] = {
commit_message_regex: '^(feat|fix|docs|style|refactor|test|chore)\(.*\): .+',
author_email_regex: '@yourcompany.com$'
}
ruby复制gitlab_rails['metrics_enabled'] = true
gitlab_rails['metrics_host'] = "0.0.0.0"
gitlab_rails['metrics_port'] = 8080
gitlab_rails['metrics_method_call_threshold'] = 1
yaml复制# alertmanager.yml
route:
receiver: 'email-alerts'
group_wait: 30s
group_interval: 5m
repeat_interval: 3h
routes:
- match:
severity: 'critical'
receiver: 'sms-alerts'
receivers:
- name: 'email-alerts'
email_configs:
- to: 'devops@yourcompany.com'
- name: 'sms-alerts'
webhook_configs:
- url: 'http://sms-gateway/api'
code复制 +-----------------+
| Load Balancer |
+--------+--------+
|
+----------------+----------------+
| | |
+-----+------+ +-----+------+ +-----+------+
| GitLab Node1| | GitLab Node2| | GitLab Node3|
+------------+ +------------+ +------------+
| | |
+-----+------+ +-----+------+ +-----+------+
| PostgreSQL | | Redis | | NFS |
| Cluster | | Sentinel | | Server |
+------------+ +------------+ +------------+
ruby复制# 在gitlab.rb中配置
postgresql['enable'] = false
gitlab_rails['db_host'] = 'postgresql-ha.yourcompany.com'
gitlab_rails['db_load_balancing'] = { 'hosts' => ['pg1.yourcompany.com', 'pg2.yourcompany.com'] }
启用对象存储:
ruby复制gitlab_rails['object_store']['enabled'] = true
gitlab_rails['object_store']['connection'] = {
'provider' => 'AWS',
'aws_access_key_id' => 'yourkey',
'aws_secret_access_key' => 'yoursecret',
'region' => 'us-east-1'
}
清理策略:
bash复制docker exec -it gitlab gitlab-rake gitlab:cleanup:project_uploads
非工作时间自动缩容:
bash复制# 使用crontab在19:00-7:00缩减资源
0 19 * * * docker update --cpus=1 gitlab
0 7 * * * docker update --cpus=4 gitlab
在旧服务器创建备份:
bash复制gitlab-rake gitlab:backup:create
将备份文件复制到新服务器:
bash复制scp /var/opt/gitlab/backups/xyz_gitlab_backup.tar newserver:/data/gitlab/backups/
恢复备份:
bash复制docker exec -it gitlab gitlab-rake gitlab:backup:restore BACKUP=xyz
建议每季度执行恢复测试:
bash复制# 创建测试环境
docker run --name gitlab-test -d gitlab/gitlab-ce:15.11.8-ce.0
# 执行恢复
docker cp latest_backup.tar gitlab-test:/var/opt/gitlab/backups/
docker exec -it gitlab-test gitlab-rake gitlab:backup:restore BACKUP=latest
在宿主机/etc/sysctl.conf中添加:
conf复制# 提高连接数上限
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
# 提高文件描述符限制
fs.file-max = 200000
# 优化TCP协议栈
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
ruby复制# 增加Unicorn workers
unicorn['worker_processes'] = 4
# 调整Puma线程池
puma['worker_processes'] = 4
puma['min_threads'] = 5
puma['max_threads'] = 10
# 优化Gitaly性能
gitaly['cgroups_count'] = 4
gitaly['cgroups_mountpoint'] = "/sys/fs/cgroup"
gitaly['cgroups_hierarchy_root'] = "gitaly"
ruby复制gitlab_rails['audit_events_enabled'] = true
gitlab_rails['audit_log_file'] = "/var/log/gitlab/audit.log"
gitlab_rails['audit_log_format'] = 'json'
启用分支保护:
code复制Settings > Repository > Protected Branches
- Require CODEOWNERS approval
- Allowed to push: Maintainers only
配置安全扫描:
yaml复制# .gitlab-ci.yml
include:
- template: Security/SAST.gitlab-ci.yml
- template: Security/Dependency-Scanning.gitlab-ci.yml
检查慢查询:
bash复制docker exec -it gitlab gitlab-rails dbconsole
> SELECT * FROM pg_stat_activity WHERE state = 'active';
分析内存使用:
bash复制docker exec -it gitlab gitaly-memory-tool analyze
测试内部连通性:
bash复制docker exec -it gitlab curl -Iv http://localhost:8080
检查DNS解析:
bash复制docker exec -it gitlab nslookup gitlab.yourdomain.com
gitlab.yml示例:
yaml复制- hosts: gitlab_servers
tasks:
- name: Ensure GitLab container running
docker_container:
name: gitlab
image: gitlab/gitlab-ce:15.11.8-ce.0
state: started
restart_policy: unless-stopped
volumes:
- "/data/gitlab/config:/etc/gitlab"
- "/data/gitlab/logs:/var/log/gitlab"
- "/data/gitlab/data:/var/opt/gitlab"
ports:
- "80:80"
- "443:443"
hcl复制resource "docker_container" "gitlab" {
name = "gitlab"
image = "gitlab/gitlab-ce:15.11.8-ce.0"
restart = "unless-stopped"
ports {
internal = 80
external = 80
}
volumes {
host_path = "/data/gitlab/config"
container_path = "/etc/gitlab"
}
}
建议采用N-1策略:
容器编排迁移:
存储架构演进:
某金融企业部署参数:
关键配置:
ruby复制unicorn['worker_processes'] = 8
sidekiq['max_concurrency'] = 50
postgresql['shared_buffers'] = '16GB'
现象:MR页面加载超过10秒
排查:
sql复制SELECT * FROM merge_request_diff_files WHERE diff_type = 'modified'
bash复制# 检查容器漏洞
docker scan gitlab/gitlab-ce:15.11.8-ce.0
# 验证文件权限
find /data/gitlab/config -type f -perm /o=w -ls
# 检查异常登录
docker exec -it gitlab grep "Failed login" /var/log/gitlab/gitlab-rails/auth.log