1. 为什么选择Docker部署GitLab?
在团队协作开发中,代码版本控制系统是基础设施中的核心组件。传统方式直接在服务器上安装GitLab需要处理复杂的依赖关系、配置系统服务以及后续的升级维护,整个过程就像在裸机上搭建一栋房子,从打地基到装修都要亲力亲为。而Docker容器化部署则像把预制好的精装房直接搬运到地块上,开箱即用。
我最近在为客户部署内部代码管理平台时,对比了三种主流方案:
- 原生安装:需要手动配置PostgreSQL、Redis、Nginx等十余个组件
- Omnibus包:虽然简化了安装但仍有系统侵入性
- Docker方案:完全隔离的环境,三行命令即可启动服务
实测下来,Docker版GitLab具有明显优势:
- 环境一致性:开发、测试、生产环境完全一致,避免"在我机器上能跑"的问题
- 资源隔离:不会污染宿主机环境,多个服务可并行运行
- 快速部署:从零到可用状态仅需10分钟(物理机部署平均需要2小时)
- 版本管理:通过镜像tag轻松切换GitLab版本
重要提示:生产环境建议至少分配4核CPU+8GB内存,GitLab是非常吃资源的应用。我在2核4GB的测试机上运行时,经常出现502错误。
2. 准备Docker运行环境
2.1 宿主机系统选择
虽然GitLab官方支持多种Linux发行版,但根据我的踩坑经验,推荐以下组合:
| 系统版本 | Docker版本 | 稳定性 | 备注 |
|---|---|---|---|
| Ubuntu 22.04 LTS | 20.10.12 | ★★★★★ | 官方推荐组合 |
| CentOS 7.9 | 19.03.15 | ★★★☆☆ | 需手动关闭SELinux |
| Debian 11 | 20.10.21 | ★★★★☆ | 社区支持较好 |
不推荐Windows Server作为宿主机,我在实际项目中遇到过文件权限和性能问题。
2.2 Docker安装与配置
以Ubuntu为例,安装最新版Docker Engine:
# 卸载旧版本 sudo apt-get remove docker docker-engine docker.io containerd runc # 设置仓库 sudo apt-get update sudo apt-get install \ 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引擎 sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin # 验证安装 sudo docker run hello-world关键配置优化(创建/etc/docker/daemon.json):
{ "log-driver": "json-file", "log-opts": { "max-size": "100m", "max-file": "3" }, "data-root": "/mnt/docker-data", "registry-mirrors": [ "https://registry.cn-hangzhou.aliyuncs.com" ] }执行sudo systemctl restart docker使配置生效。
3. GitLab容器化部署实战
3.1 单容器快速部署方案
对于小型团队(<20人),可以使用官方all-in-one镜像:
sudo docker run --detach \ --hostname gitlab.example.com \ --publish 443:443 --publish 80:80 --publish 22:22 \ --name gitlab \ --restart always \ --volume /srv/gitlab/config:/etc/gitlab \ --volume /srv/gitlab/logs:/var/log/gitlab \ --volume /srv/gitlab/data:/var/opt/gitlab \ --shm-size 256m \ gitlab/gitlab-ce:latest这个命令做了以下几件重要事情:
- 映射了HTTP(80)、HTTPS(443)和SSH(22)端口
- 挂载了三个持久化卷(配置、日志、数据)
- 设置了256MB的共享内存(解决Sidekiq内存问题)
- 使用最新社区版镜像(gitlab/gitlab-ce)
首次启动需要5-10分钟初始化,可以通过docker logs -f gitlab查看进度。当看到以下日志时表示启动完成:
gitlab Reconfigured! gitlab Logrotate rotated: /var/log/gitlab/gitaly/current -> /var/log/gitlab/gitaly/current.13.2 生产级多容器部署
对于50人以上的团队,建议将服务拆分为多个容器:
# docker-compose.yml version: '3' services: postgresql: image: postgres:13 environment: POSTGRES_PASSWORD: "strongpassword" POSTGRES_USER: gitlab POSTGRES_DB: gitlabhq_production volumes: - postgresql-data:/var/lib/postgresql/data restart: always redis: image: redis:6 command: ["redis-server", "--requirepass redispassword"] volumes: - redis-data:/data restart: always gitlab: image: gitlab/gitlab-ce:latest depends_on: - postgresql - redis environment: GITLAB_OMNIBUS_CONFIG: | external_url 'https://gitlab.example.com' gitlab_rails['db_adapter'] = 'postgresql' gitlab_rails['db_encoding'] = 'unicode' gitlab_rails['db_host'] = 'postgresql' gitlab_rails['db_password'] = 'strongpassword' gitlab_rails['redis_host'] = 'redis' gitlab_rails['redis_password'] = 'redispassword' ports: - "80:80" - "443:443" - "22:22" volumes: - gitlab-config:/etc/gitlab - gitlab-logs:/var/log/gitlab - gitlab-data:/var/opt/gitlab shm_size: '256m' restart: always volumes: postgresql-data: redis-data: gitlab-config: gitlab-logs: gitlab-data:启动命令:docker-compose up -d
这种架构的优势在于:
- 数据库可独立扩展
- 各组件资源配额可分别设置
- 故障隔离性更好
- 备份策略更灵活
4. 初始配置与优化技巧
4.1 首次访问配置
当容器启动完成后,访问http://服务器IP 会跳转到密码设置页面。建议:
为root用户设置强密码(16位以上含特殊字符)
立即配置SMTP邮件服务(否则用户无法注册)
修改/srv/gitlab/config/gitlab.rb(单容器方案):
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'] = "password" 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'执行
docker exec -it gitlab gitlab-ctl reconfigure应用更改。
4.2 性能调优参数
在/srv/gitlab/config/gitlab.rb中添加这些关键配置:
# 工作进程数 = CPU核心数 + 1 unicorn['worker_processes'] = 4 # 数据库连接池大小 postgresql['max_worker_processes'] = 8 postgresql['shared_buffers'] = "256MB" # Sidekiq并发数 sidekiq['concurrency'] = 10 # 缓存配置 redis['max_memory'] = "1GB" redis['maxmemory_policy'] = "allkeys-lru" # 定期执行housekeeping gitlab_rails['gitlab_shell_git_timeout'] = 18004.3 备份与恢复方案
手动备份:
docker exec -t gitlab gitlab-backup create备份文件会存储在/srv/gitlab/data/backups目录下。
自动备份(每天2点执行):
# 创建备份脚本 /usr/local/bin/gitlab-backup.sh #!/bin/bash docker exec -t gitlab gitlab-backup create && \ find /srv/gitlab/data/backups -mtime +7 -name "*.tar" -delete # 添加cron任务 0 2 * * * /usr/local/bin/gitlab-backup.sh恢复备份:
# 停止相关服务 docker exec -it gitlab gitlab-ctl stop unicorn docker exec -it gitlab gitlab-ctl stop sidekiq # 执行恢复(BACKUP=备份文件名不含_gitlab_backup.tar) docker exec -it gitlab gitlab-backup restore BACKUP=123456789_2023_08_01 # 重启服务 docker exec -it gitlab gitlab-ctl restart5. 常见问题排查指南
5.1 502错误处理
这是最常见的问题,通常由以下原因导致:
内存不足:
docker exec -it gitlab free -m如果可用内存<1GB,需要:
- 增加宿主机内存
- 调整Unicorn worker数量
- 添加swap空间
端口冲突:
ss -tulnp | grep -E '80|443|22'如果其他进程占用了这些端口,需要修改GitLab端口映射或停止冲突服务。
启动超时: 查看日志:
docker logs --tail 100 gitlab首次启动可能需要15分钟以上,耐心等待。
5.2 SSH克隆失败
如果出现git clone git@example.com:project.git连接超时:
检查22端口映射:
docker inspect gitlab | grep HostPort确保HostPort是22
检查容器内SSH服务状态:
docker exec -it gitlab gitlab-ctl status | grep ssh如果宿主机SSH也使用22端口,需要:
- 修改宿主机SSH端口
- 或者使用非标准端口映射(如2222:22)
5.3 磁盘空间告警
GitLab会快速消耗磁盘空间,处理方案:
清理Docker系统:
docker system prune -af清理GitLab无用数据:
docker exec -it gitlab gitlab-rake gitlab:cleanup:project_uploads docker exec -it gitlab gitlab-rake gitlab:cleanup:orphan_job_artifact_files设置自动清理(在gitlab.rb中):
gitlab_rails['uploads_object_store_enabled'] = true gitlab_rails['uploads_object_store_background_upload'] = true
6. 进阶配置与扩展
6.1 集成LDAP/AD认证
编辑gitlab.rb添加:
gitlab_rails['ldap_enabled'] = true gitlab_rails['ldap_servers'] = { 'main' => { 'label' => 'Company AD', 'host' => 'ad.example.com', 'port' => 636, 'uid' => 'sAMAccountName', 'encryption' => 'simple_tls', 'verify_certificates' => true, 'bind_dn' => 'CN=GitLab Sync,OU=Service Accounts,DC=example,DC=com', 'password' => 'password', 'active_directory' => true, 'base' => 'OU=Users,DC=example,DC=com', 'group_base' => 'OU=Groups,DC=example,DC=com', 'admin_group' => 'GitLab Admins' } }6.2 CI/CD Runner部署
- 创建Runner容器:
docker run -d --name gitlab-runner --restart always \ -v /srv/gitlab-runner/config:/etc/gitlab-runner \ -v /var/run/docker.sock:/var/run/docker.sock \ gitlab/gitlab-runner:latest- 注册Runner:
docker exec -it gitlab-runner gitlab-runner register \ --url "http://gitlab.example.com/" \ --registration-token "PROJECT_REGISTRATION_TOKEN" \ --executor "docker" \ --docker-image alpine:latest \ --description "docker-runner" \ --tag-list "docker,aws" \ --run-untagged="true" \ --locked="false"6.3 监控方案
推荐使用以下组合监控GitLab容器:
- Prometheus:内置/metrics端点
- Grafana:官方提供GitLab仪表板模板
- ELK:收集和分析日志
示例docker-compose监控配置:
monitoring: image: prom/prometheus ports: - "9090:9090" volumes: - ./prometheus.yml:/etc/prometheus/prometheus.yml depends_on: - gitlab grafana: image: grafana/grafana ports: - "3000:3000" volumes: - grafana-data:/var/lib/grafana在GitLab服务器上,我习惯添加一个简单的监控脚本check_gitlab.sh:
#!/bin/bash HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost/-/health) if [ "$HTTP_CODE" != "200" ]; then echo "GitLab服务异常!HTTP状态码: $HTTP_CODE" | mail -s "GitLab监控告警" admin@example.com docker restart gitlab fi