我们已经有了从云服务器取回文件的方案,现在的核心需求是:在服务器端,定期、自动地导出 Docker 中的 MySQL 数据,压缩并保存到指定目录(挂载卷)。
考虑到需要“简单、稳定、现成”的方案,且接受部署一个新的 Docker 容器,强烈推荐使用专门的 Docker 备份镜像。因为成熟的镜像已经封装好了 mysqldump、crontab(定时任务)、gzip(压缩)以及过期备份自动清理(Retention)的逻辑。
这里推荐使用业界非常流行且轻量的镜像:fradelg/mysql-cron-backup (或者类似的变体)。
解决方案架构
你将在服务器上创建一个独立的 docker-compose.yml 来管理备份服务。因为你有 2个 MySQL 实例,最简单稳定的做法是起 2个轻量级备份容器,分别对应两个数据库实例。这样互不干扰,配置清晰。
操作步骤
1. 准备工作:确认网络
由于备份容器需要连接到现有的 MySQL 容器,它们需要能够互相通信。
- 情况 A:如果你现有的 MySQL 都在同一个 Docker 网络中(比如
my-network),你只需把备份容器加入该网络。 - 情况 B:如果你现有的 MySQL 直接映射端口到了宿主机的 3306/3307,你也可以让备份容器通过宿主机的 IP 访问(不推荐,走 Docker 网络更安全)。
假设你现有的两个 MySQL 容器名分别为 mysql_container_1 和 mysql_container_2,且它们都在名为 app_net 的网络中。
2. 创建备份服务的 Docker Compose
在服务器上新建一个目录,例如 /opt/db-backups,并在其中创建 docker-compose.yml:
version: '3'
services:
# --- 备份第一个 MySQL 实例 ---
backup-db-1:
image: fradelg/mysql-cron-backup
container_name: backup-worker-1
depends_on:
- mysql_container_1 # 确保能找到目标容器(如果不在同一个compose文件可忽略此行,但必须在同网络)
volumes:
# 将容器内的备份目录映射到宿主机的物理路径
- ./data/db1:/backup
environment:
# 数据库连接信息
- MYSQL_HOST=mysql_container_1 # 现有 MySQL 容器的服务名或容器名
- MYSQL_PORT=3306
- MYSQL_USER=root # 建议创建一个只读权限的备份专用账号,省事则用root
- MYSQL_PASS=your_password_1
# 要备份的数据库名称,多个数据库用空格隔开,备份所有库填 *
- MYSQL_DATABASE=db_name_a db_name_b
# 压缩选项
- GZIP_LEVEL=9 # 最高压缩比
# 定时任务 (Cron 表达式)
- CRON_TIME=0 3 * * * # 每天凌晨 3:00 执行
# 保留策略
- MAX_BACKUPS=7 # 本地只保留最近 7 个备份文件,自动删除旧的
- INIT_BACKUP=0 # 启动容器时是否立即备份一次 (0=否, 1=是)
networks:
- app_net # 必须与你的 MySQL 容器在同一个网络
# --- 备份第二个 MySQL 实例 ---
backup-db-2:
image: fradelg/mysql-cron-backup
container_name: backup-worker-2
volumes:
- ./data/db2:/backup
environment:
- MYSQL_HOST=mysql_container_2
- MYSQL_PORT=3306
- MYSQL_USER=root
- MYSQL_PASS=your_password_2
- MYSQL_DATABASE=other_db_x
- GZIP_LEVEL=9
- CRON_TIME=0 3 * * * # 也可以设置不同时间错峰备份
- MAX_BACKUPS=7
networks:
- app_net
# 定义网络(声明这是一个外部已存在的网络)
networks:
app_net:
external: true
3. 部署并验证
- 启动服务:
docker-compose up -d - 测试备份:
你可以手动进入容器触发一次备份,或者修改INIT_BACKUP=1重启容器来测试配置是否正确。# 手动执行一次脚本进行测试 docker exec backup-worker-1 /backup.sh - 查看结果:
检查宿主机的./data/db1目录,你应该能看到类似db_name_a-20231027-0300.sql.gz的文件。
为什么选择这个方案?
- 解耦与隔离:两个 MySQL 对应两个备份容器,如果其中一个数据库挂了或者配置变了,不会影响另一个的备份任务。
- 简单稳定:使用的是
mysqldump原生工具,加上简单的 Shell 脚本控制,没有复杂的逻辑,极不容易出错。 - 功能齐全:
- 定时:内置 Cron,不需要配置宿主机的 Crontab。
- 压缩:直接生成
.gz文件,节省带宽和空间。 - 轮转:
MAX_BACKUPS参数非常关键,它能防止你的磁盘被无限增长的备份文件填满,自动清理旧文件。
- 无状态:容器坏了删掉重开即可,配置都在
docker-compose.yml里。
总结建议
直接使用 fradelg/mysql-cron-backup 的 Docker Compose 方案。这是最符合“简单、稳定、现成”标准的做法,几行配置就能搞定两个数据库的定时备份、压缩和自动清理。