Docker 部署 MySQL
本文是一份独立于具体项目的 MySQL 容器部署参考。示例默认只把端口绑定到本机回环地址,适合本地开发、测试或作为生产配置的起点。
版本与目录
示例使用官方镜像的 mysql:8.4 标签。上线前应结合兼容性测试固定补丁版本或镜像摘要,避免浮动标签在重建时改变实际镜像。
建议使用以下目录:
mysql/
├── compose.yaml
├── .env
└── secrets/
├── mysql-root-password.txt
└── mysql-app-password.txt
将 .env 和 secrets/ 加入版本控制忽略列表。密码文件中只放一行随机密码,不要提交到仓库。
mkdir -p mysql/secrets
cd mysql
umask 077
openssl rand -base64 32 > secrets/mysql-root-password.txt
openssl rand -base64 32 > secrets/mysql-app-password.txt
.env 只保存非敏感设置:
MYSQL_DATABASE=app_db
MYSQL_USER=app_user
Docker Compose
services:
mysql:
image: mysql:8.4
restart: unless-stopped
ports:
- "127.0.0.1:3306:3306"
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/mysql_root_password
MYSQL_DATABASE: ${MYSQL_DATABASE:?set MYSQL_DATABASE in .env}
MYSQL_USER: ${MYSQL_USER:?set MYSQL_USER in .env}
MYSQL_PASSWORD_FILE: /run/secrets/mysql_app_password
secrets:
- mysql_root_password
- mysql_app_password
volumes:
- mysql-data:/var/lib/mysql
healthcheck:
test:
- CMD-SHELL
- mysqladmin ping -h 127.0.0.1 -uroot -p"$$(cat /run/secrets/mysql_root_password)" --silent
interval: 10s
timeout: 5s
retries: 10
start_period: 30s
secrets:
mysql_root_password:
file: ./secrets/mysql-root-password.txt
mysql_app_password:
file: ./secrets/mysql-app-password.txt
volumes:
mysql-data:
mysql-data 挂载到镜像的数据目录 /var/lib/mysql。删除并重建容器不会删除命名卷;删除卷则会永久删除数据库文件。
如果应用也在同一份 Compose 配置中,应通过服务名 mysql:3306 连接,无需把 3306 发布到宿主机。需要远程访问时,应优先通过私有网络、VPN 或受控隧道访问,不要直接把数据库端口暴露到公网。
启动与验证
docker compose config
docker compose up -d
docker compose ps
docker compose logs --tail=100 mysql
健康检查通过后,以应用用户连接:
docker compose exec mysql mysql -u app_user -p app_db
命令会交互式询问密码,避免把密码写入 shell 历史。初始化变量只在空数据目录的首次启动时生效;已有数据库卷不会因修改 .env 而自动更改用户或密码。
自定义配置与初始化
自定义配置可只读挂载到 /etc/mysql/conf.d/:
services:
mysql:
volumes:
- mysql-data:/var/lib/mysql
- ./conf.d:/etc/mysql/conf.d:ro
首次初始化脚本可挂载到 /docker-entrypoint-initdb.d:ro。官方镜像只会在数据目录为空时执行该目录中的受支持脚本;脚本必须可重复审查,并且不能包含明文凭据。
备份与恢复
先创建仅管理员可读的备份目录:
mkdir -p backups
chmod 700 backups
导出所有数据库:
docker compose exec -T mysql sh -c 'exec mysqldump --all-databases --single-transaction -uroot -p"$(cat /run/secrets/mysql_root_password)"' > backups/all-databases.sql
恢复会改写目标实例中的数据,必须先在隔离环境验证备份内容和恢复流程:
docker compose exec -T mysql sh -c 'exec mysql -uroot -p"$(cat /run/secrets/mysql_root_password)"' < backups/all-databases.sql
--single-transaction 主要用于事务型表;存在非事务型表、超大数据集或严格恢复点目标时,应采用适合业务的 MySQL 备份方案。备份文件同样包含敏感数据,应加密、限制权限并保存到独立存储。
停止与清理
docker compose stop
docker compose down
docker compose down 默认保留命名卷。只有确认备份已验证且数据不再需要时,才可使用 docker compose down -v;该命令会删除 mysql-data,不可依靠重新创建容器恢复。