Docker Compose编排GitLab:从单机部署到生产级配置

📅 2026/7/14 5:24:29 👁️ 阅读次数 📝 编程学习
Docker Compose编排GitLab:从单机部署到生产级配置

1. 为什么选择Docker Compose部署GitLab

第一次接触GitLab时,我尝试过直接在服务器上安装,结果被复杂的依赖关系和配置过程折磨得够呛。后来发现用Docker部署简直像发现了新大陆——特别是配合Docker Compose,所有服务都能通过一个YAML文件搞定。这种"基础设施即代码"的方式,让部署过程变得可重复、可版本控制。

GitLab官方提供的Docker镜像已经预配置了所有必要组件(包括Nginx、PostgreSQL、Redis等),但默认的单容器方案并不适合生产环境。我在实际项目中踩过的坑包括:数据丢失风险、性能瓶颈、升级困难等。而通过Docker Compose编排,可以实现:

  • 服务分离:数据库、缓存等组件独立部署
  • 资源隔离:为不同服务分配CPU/内存限制
  • 灵活扩展:未来可轻松添加CI Runner等组件

2. 基础环境准备

2.1 硬件资源配置建议

根据我的经验,GitLab对资源的需求是这样的:

  • 开发测试环境:2核CPU/4GB内存/50GB存储
  • 20人团队生产环境:4核CPU/8GB内存/200GB存储
  • 100人以上团队:建议8核CPU/16GB内存+SSD存储

特别提醒:GitLab运行时会启动多个Unicorn worker进程,内存不足会导致502错误。我曾在一个2GB内存的机器上部署,结果频繁崩溃,后来发现官方建议至少4GB。

2.2 软件依赖安装

首先确保宿主机已安装最新版Docker和Docker Compose:

# 安装Docker curl -fsSL https://get.docker.com | sh sudo systemctl enable --now docker # 安装Docker Compose sudo curl -L "https://github.com/docker/compose/releases/download/v2.23.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose

验证安装:

docker --version # 应显示Docker版本 docker-compose --version # 应显示Compose版本

3. 编写docker-compose.yml文件

3.1 最小化生产配置

这是我经过多个项目验证的基础模板:

version: '3.8' services: gitlab: image: gitlab/gitlab-ce:latest container_name: gitlab hostname: gitlab.yourdomain.com restart: unless-stopped environment: GITLAB_OMNIBUS_CONFIG: | external_url 'https://gitlab.yourdomain.com' gitlab_rails['time_zone'] = 'Asia/Shanghai' gitlab_rails['gitlab_shell_ssh_port'] = 2222 ports: - "80:80" - "443:443" - "2222:22" volumes: - ./gitlab/config:/etc/gitlab - ./gitlab/logs:/var/log/gitlab - ./gitlab/data:/var/opt/gitlab shm_size: '256m'

关键参数说明:

  • hostname:必须设置为最终访问的域名
  • GITLAB_OMNIBUS_CONFIG:GitLab的核心配置
  • shm_size:解决Sidekiq内存不足问题

3.2 集成PostgreSQL和Redis

生产环境建议使用独立数据库:

services: postgres: image: postgres:13 container_name: gitlab-postgres environment: POSTGRES_USER: gitlab POSTGRES_PASSWORD: your_strong_password POSTGRES_DB: gitlabhq_production volumes: - ./postgres/data:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U gitlab"] interval: 10s timeout: 5s retries: 5 redis: image: redis:6 container_name: gitlab-redis command: ["redis-server", "--requirepass yourredispassword"] volumes: - ./redis/data:/data restart: unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 gitlab: depends_on: postgres: condition: service_healthy redis: condition: service_healthy environment: GITLAB_OMNIBUS_CONFIG: | postgresql['enable'] = false redis['enable'] = false gitlab_rails['db_adapter'] = 'postgresql' gitlab_rails['db_host'] = 'postgres' gitlab_rails['db_port'] = 5432 gitlab_rails['db_username'] = 'gitlab' gitlab_rails['db_password'] = 'your_strong_password' gitlab_rails['redis_host'] = 'redis' gitlab_rails['redis_port'] = 6379 gitlab_rails['redis_password'] = 'yourredispassword'

4. HTTPS安全配置

4.1 自动获取Let's Encrypt证书

最简便的HTTPS配置方式:

environment: GITLAB_OMNIBUS_CONFIG: | letsencrypt['enable'] = true letsencrypt['contact_emails'] = ['admin@yourdomain.com'] letsencrypt['auto_renew'] = true letsencrypt['auto_renew_hour'] = 0 letsencrypt['auto_renew_minute'] = 30 letsencrypt['auto_renew_day_of_month'] = "*/4"

4.2 手动配置已有证书

如果有商业证书,可以这样配置:

mkdir -p gitlab/config/ssl # 将证书文件放入gitlab/config/ssl # 重命名为gitlab.yourdomain.com.crt和gitlab.yourdomain.com.key

然后在docker-compose.yml中添加:

environment: GITLAB_OMNIBUS_CONFIG: | nginx['ssl_certificate'] = "/etc/gitlab/ssl/gitlab.yourdomain.com.crt" nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/gitlab.yourdomain.com.key" nginx['redirect_http_to_https'] = true

5. 生产环境优化配置

5.1 资源限制与健康检查

防止GitLab占用过多资源:

gitlab: deploy: resources: limits: cpus: '2' memory: 4G reservations: memory: 2G healthcheck: test: ["CMD", "/opt/gitlab/bin/gitlab-healthcheck", "--fail"] interval: 1m timeout: 10s retries: 3

5.2 邮件通知配置

以腾讯企业邮箱为例:

environment: GITLAB_OMNIBUS_CONFIG: | 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'] = "your_password" 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'

测试邮件发送:

docker exec -it gitlab gitlab-rails console Notify.test_email('recipient@example.com', 'Test Subject', 'Test Body').deliver_now

6. 日常维护操作

6.1 数据备份与恢复

配置自动备份:

environment: GITLAB_OMNIBUS_CONFIG: | gitlab_rails['backup_path'] = "/var/opt/gitlab/backups" gitlab_rails['backup_keep_time'] = 604800 # 保留7天

手动备份命令:

docker exec -it gitlab gitlab-backup create

恢复备份:

# 先将备份文件放入gitlab/data/backups docker exec -it gitlab gitlab-backup restore BACKUP=文件名前缀

6.2 版本升级步骤

安全升级流程:

  1. 停止当前容器:docker-compose stop gitlab
  2. 备份数据:docker-compose exec gitlab gitlab-backup create
  3. 拉取新镜像:docker-compose pull gitlab
  4. 启动新版本:docker-compose up -d gitlab
  5. 监控日志:docker-compose logs -f gitlab

建议在非工作时间进行升级,大型版本升级(如14→15)可能需要更长时间。

7. 常见问题排查

问题1:502 Whoops错误

  • 检查内存是否不足:docker stats gitlab
  • 查看日志:docker logs --tail 100 gitlab
  • 解决方案:增加内存或调整Unicorn worker数量

问题2:SSH克隆失败

  • 确认gitlab_rails['gitlab_shell_ssh_port']与映射端口一致
  • 检查防火墙规则:iptables -L -n

问题3:邮件发送失败

  • 测试Telnet连接:docker exec -it gitlab telnet smtp.exmail.qq.com 465
  • 检查垃圾邮件箱
  • 尝试更换端口(465/587)

问题4:容器启动超时

  • 增加启动超时时间:
    gitlab: deploy: resources: limits: cpus: '4' memory: 8G healthcheck: start_period: 10m

记得第一次成功部署GitLab后,我兴奋地给团队发邮件通知,结果因为SMTP配置错误,所有人都没收到邮件。后来通过docker exec -it gitlab tail -f /var/log/gitlab/mailroom/current才找到问题所在——邮箱密码里有个特殊字符需要转义。这种实战经验,才是真正宝贵的知识。