1. 为什么选择Docker部署Gogs

作为团队技术负责人,我经历过多次自建Git服务的痛苦过程。从早期的物理机部署到虚拟机环境,每次遇到系统升级或迁移都是噩梦。直到发现Docker+Gogs这个黄金组合,才真正解决了私有代码仓库的部署难题。

Gogs是用Go语言编写的轻量级Git服务,相比GitLab这类庞然大物,它的资源占用只有后者的1/10。我实测过在1核2G的云服务器上,Gogs能稳定支持20人团队的日常开发。而Docker的容器化部署,让整个安装过程从原来的2小时缩短到15分钟。

最让我惊喜的是数据持久化方案。去年我们服务器意外宕机,重启后所有代码仓库完好无损——这得益于Docker的volume挂载机制。现在团队新成员入职,我只需要发个docker-compose文件,他们就能在本地一键搭建相同的开发环境。

2. 生产环境准备工作

2.1 硬件资源配置建议

根据我们团队50人规模的经验,推荐以下配置:

  • 开发团队规模:CPU核心数=团队人数/20(向上取整)
  • 内存分配:基础2GB + 每用户50MB
  • 存储空间:代码仓库容量 × 3(考虑版本历史)

比如我们团队使用4核8GB的云主机,挂载200GB SSD硬盘,实际监控显示日常CPU利用率不到30%。

2.2 目录结构规划

避免把数据直接扔在/root下,推荐专业化的目录结构:

mkdir -p /opt/gogs/{data,backup,conf}
chmod -R 775 /opt/gogs

这里有个坑要注意:如果使用SELinux的环境,需要额外执行:

chcon -Rt svirt_sandbox_file_t /opt/gogs

2.3 网络端口规划

生产环境建议避开常用端口:

  • Web界面:建议3000→13000(避免与Prometheus冲突)
  • SSH服务:建议22→10022(增强安全性)

防火墙配置示例:

firewall-cmd --permanent --add-port=13000/tcp
firewall-cmd --permanent --add-port=10022/tcp
firewall-cmd --reload

3. 容器化部署实战

3.1 镜像选择策略

官方镜像有两个版本需要注意:

# 稳定版(推荐生产环境使用)
docker pull gogs/gogs:0.13

# 最新版(适合尝鲜)
docker pull gogs/gogs:latest

我踩过的坑:某次使用latest标签升级后,MySQL驱动出现兼容性问题。现在团队规定生产环境必须锁定版本号。

3.2 初始化容器技巧

先启动临时容器获取配置文件:

docker run -d --name=gogs-temp \
  -p 10022:22 \
  -p 13000:3000 \
  -v /opt/gogs/data:/data \
  gogs/gogs:0.13

复制关键配置文件的正确姿势:

docker cp gogs-temp:/data/gogs/conf/app.ini /opt/gogs/conf/
docker cp gogs-temp:/data/gogs/custom/conf/app.ini /opt/gogs/conf/custom.conf

3.3 生产级容器启动

这才是真正用于生产的启动命令:

docker run -d \
  --name=gogs \
  -p 10022:22 \
  -p 13000:3000 \
  -v /opt/gogs/data:/data \
  -v /opt/gogs/backup:/backup \
  -v /opt/gogs/conf:/data/gogs/conf \
  -e TZ="Asia/Shanghai" \
  --restart=unless-stopped \
  --health-cmd="curl -f http://localhost:3000/healthcheck || exit 1" \
  --health-interval=30s \
  gogs/gogs:0.13

重点参数解析:

  • --restart=unless-stopped:比always更智能的重启策略
  • --health-check:添加健康检查避免僵尸进程
  • 三级挂载:数据、备份、配置分离管理

4. 关键配置调优

4.1 时区与语言设置

修改/opt/gogs/conf/app.ini:

[server]
DOMAIN = git.yourcompany.com
HTTP_PORT = 3000
ROOT_URL = http://git.yourcompany.com:13000

[i18n]
LANGS = en-US,zh-CN
NAMES = English,简体中文

4.2 邮件服务配置

必须设置的SMTP参数(以腾讯企业邮箱为例):

[mailer]
ENABLED = true
HOST = smtp.exmail.qq.com:465
FROM = git@yourcompany.com
USER = git@yourcompany.com
PASSWD = yourpassword
SKIP_VERIFY = true

4.3 数据库优化

内置SQLite的优化方案:

[database]
DB_TYPE = sqlite3
PATH = /data/gogs/data/gogs.db
SSL_MODE = disable
ITERATE_BUFFER_SIZE = 50

MySQL生产配置建议:

[database]
DB_TYPE = mysql
HOST = mysql-container:3306
NAME = gogs
USER = gogs
PASSWD = yourpassword

5. 运维监控与维护

5.1 日志查看技巧

实时查看日志的正确姿势:

docker logs -f --tail 100 gogs  # 实时追踪最后100行

日志文件位置:

  • 容器内:/app/gogs/log
  • 宿主机:/opt/gogs/data/gogs/log

5.2 备份方案

全量备份命令示例:

docker exec gogs sh -c 'cd /app/gogs && ./gogs backup --target=/backup'

可以添加到crontab的自动化脚本:

0 3 * * * docker exec gogs sh -c 'cd /app/gogs && ./gogs backup --target=/backup --database-only'

5.3 性能监控

内置的Prometheus监控配置:

[metrics]
ENABLED = true
TOKEN = your_token

配合Grafana的监控看板指标:

  • git_push_requests_total
  • git_pull_requests_total
  • repo_creating_total

6. 安全加固措施

6.1 SSH安全配置

修改SSH端口后需要同步调整:

[server]
SSH_PORT = 10022
SSH_LISTEN_PORT = 22
DISABLE_SSH = false

6.2 防暴力破解

启用登录限制:

[security]
LOGIN_ATTEMPT_LIMIT = 10
LOGIN_ATTEMPT_WINDOW = 5

6.3 定期升级策略

我们的升级checklist:

  1. 执行完整备份
  2. 停止旧容器
  3. 拉取新镜像
  4. 启动测试容器验证
  5. 生产环境切换

升级命令示例:

docker stop gogs
docker rm gogs
docker pull gogs/gogs:0.14
# 使用原有参数重新运行

7. 踩坑经验分享

7.1 权限问题解决

遇到过最头疼的权限错误:

chown -R 1000:1000 /opt/gogs/data

因为Gogs容器默认使用uid=1000的用户运行,必须确保挂载目录权限正确。

7.2 时区同步问题

除了设置TZ环境变量,还要检查:

docker exec gogs date

如果显示时间不对,可能需要重建镜像:

FROM gogs/gogs:0.13
RUN apk add tzdata && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

7.3 内存泄漏排查

某次OOM事故后的解决方案:

  1. 限制容器内存:
--memory=2g --memory-swap=2g
  1. 调整Gogs的GC参数:
[server]
PROFILER = false

8. 团队协作配置

8.1 LDAP集成

企业级认证配置示例:

[auth.ldap]
ENABLED = true
HOST = ldap://ldap-server
BIND_DN = cn=admin,dc=company,dc=com
USER_SEARCH_BASE = ou=users,dc=company,dc=com

8.2 Web钩子管理

实用的Git钩子示例:

#!/bin/bash
# /opt/gogs/data/git/git-hooks/post-receive.d/notify
curl -X POST -H "Content-Type: application/json" \
  -d '{"text":"New push to $REPO"}' \
  https://chat.yourcompany.com/hook

8.3 代码审查流程

我们团队的branch保护策略:

  • master分支:需要2个approve才能合并
  • release分支:禁止force push
  • 所有分支:必须通过CI检测

更多推荐