企业级Gitea与MySQL容器化部署实战:从配置到灾备的全套解决方案

当团队规模扩张到5-20人时,代码管理往往成为第一个需要专业化的基础设施。我曾为三家初创公司搭建过内部Git服务,发现多数技术负责人在选择自建方案时最纠结的不是功能,而是如何在简化部署的同时保障企业级可靠性。这正是Docker Compose结合Gitea的魅力所在——用单个配置文件实现开箱即用的代码托管平台,同时满足生产环境对数据安全和服务稳定的严苛要求。

1. 生产级架构设计原则

1.1 容器编排的黄金分割点

在Windows Server环境下部署Gitea,我们需要在便捷性和可靠性之间找到平衡点。以下是一个经过三次迭代优化的docker-compose.yml核心框架:

version: "3.8"

services:
  gitea:
    image: gitea/gitea:1.16.9
    container_name: gitea_app
    environment:
      - USER_UID=1001
      - USER_GID=1001
      - DB_TYPE=mysql
      - DB_HOST=mysql_db:3306
    volumes:
      - ./gitea_data:/data
      - ./gitea_etc/localtime:/etc/localtime:ro
    ports:
      - "13480:3000"
      - "13422:22"
    depends_on:
      - mysql_db
    networks:
      - gitea_net

  mysql_db:
    image: mysql:8.0.28
    container_name: gitea_mysql
    environment:
      - MYSQL_ROOT_PASSWORD=ComplexP@ssw0rd!
      - MYSQL_USER=gitea_admin
      - MYSQL_PASSWORD=GiteaAdmin@123
    volumes:
      - ./mysql_data:/var/lib/mysql
      - ./mysql_conf:/etc/mysql/conf.d
    networks:
      - gitea_net
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 3

networks:
  gitea_net:
    driver: bridge
    ipam:
      config:
        - subnet: 172.22.0.0/24

这个设计有几个关键改进:

  • 使用固定版本镜像而非latest标签
  • 为MySQL添加健康检查机制
  • 自定义网络子网避免IP冲突
  • 非root用户运行降低安全风险

1.2 持久化存储策略优化

数据持久化不是简单的目录映射那么简单。我们采用分层存储策略:

数据类型存储位置备份频率恢复优先级
代码仓库./gitea_data/git每日增量最高(P0)
MySQL数据./mysql_data每小时binlogP0
附件文件./gitea_data/attachments每日全量P1
配置文件./gitea_data/conf配置变更时P2

在Windows环境下要特别注意:

  • 使用相对路径避免驱动器字母变更导致失效
  • NTFS权限需要显式设置:
    icacls .\gitea_data /grant "Everyone:(OI)(CI)(F)"
    icacls .\mysql_data /grant "NETWORK SERVICE:(OI)(CI)(F)"
    

2. 高可用配置实战

2.1 MySQL性能调优三板斧

./mysql_conf/my.cnf中添加以下优化参数:

[mysqld]
innodb_buffer_pool_size = 512M
innodb_log_file_size = 256M
max_connections = 200
thread_cache_size = 16
query_cache_type = 0

通过docker-compose重启服务后,使用这个命令验证效果:

docker exec -it gitea_mysql mysql -u root -p -e "SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_read%';"

2.2 Gitea的HTTP优化

对于10人以上团队,建议在Gitea前部署Nginx反向代理。这里给出一个精简配置:

server {
    listen 80;
    server_name git.yourcompany.com;

    location / {
        proxy_pass http://localhost:13480;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    client_max_body_size 100M;
}

注意:Windows版的Nginx需要将路径中的/替换为\,并确保worker_processes不超过CPU核心数

3. 自动化备份方案

3.1 数据库热备份脚本

创建backup_mysql.ps1 PowerShell脚本:

$backupDir = ".\backups\mysql"
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
New-Item -ItemType Directory -Path $backupDir -Force

docker exec gitea_mysql mysqldump -u root -pComplexP@ssw0rd! --single-transaction --routines --triggers gitea | gzip > "$backupDir\gitea_$timestamp.sql.gz"

# 保留最近7天备份
Get-ChildItem $backupDir | Sort-Object LastWriteTime -Descending | Select-Object -Skip 7 | Remove-Item -Force

添加到Windows任务计划程序,设置为每小时运行。

3.2 Gitea元数据备份

利用Gitea自带的dump命令更可靠:

docker exec gitea_app sh -c 'gitea dump -c /data/gitea/conf/app.ini --tempdir /tmp'
docker cp gitea_app:/data/gitea/dump.zip .\backups\gitea\dump_$(Get-Date -Format "yyyyMMdd").zip

4. 灾备恢复演练

4.1 MySQL数据恢复步骤

当需要从备份恢复时:

# 解压备份文件
gunzip -c .\backups\mysql\gitea_20230601_1200.sql.gz | docker exec -i gitea_mysql mysql -u root -pComplexP@ssw0rd! gitea

# 验证数据完整性
docker exec gitea_mysql mysql -u root -pComplexP@ssw0rd! -e "SELECT COUNT(*) FROM gitea.repository"

4.2 Gitea全量恢复

  1. 停止现有服务:docker-compose down
  2. 清空数据卷:Remove-Item .\gitea_data\* -Recurse -Force
  3. 解压dump文件到gitea_data目录
  4. 重新启动:docker-compose up -d

5. 日常运维技巧

5.1 日志监控方案

组合使用这些命令进行实时监控:

# 查看Gitea实时日志
Get-Content -Path .\gitea_data\gitea\log\gitea.log -Wait -Tail 50

# MySQL慢查询分析
docker exec gitea_mysql mysqldumpslow -s t /var/lib/mysql/mysql-slow.log

5.2 服务升级流程

  1. 停止服务:docker-compose down
  2. 备份所有数据卷
  3. 修改compose文件中的镜像版本
  4. 重建容器:docker-compose up -d --force-recreate
  5. 执行Gitea升级:docker exec gitea_app gitea manager flush-queues

在最近一次升级中,我们发现从1.15升级到1.16时需要特别注意OAuth2配置的迁移。建议先在测试环境验证升级流程,特别是当团队使用了第三方登录集成时。

更多推荐