Docker MySQL 部署指南
本文介绍如何使用 Docker 和 Docker Compose 部署 MySQL 数据库服务。MySQL 是最流行的开源关系型数据库管理系统之一。
📋 前置要求
- Docker 20.10+ 已安装
- Docker Compose V2 已安装(推荐)或 Docker Compose V1
- 如需使用 Docker Swarm,需要初始化 Swarm 集群
- 如需使用 NFS,需要配置 NFS 服务器
🚀 快速部署(Docker Compose)
1. 克隆项目(如果使用项目模板)
1 2
| git clone https://github.com/noahzaozao/docker-mysql.git cd docker-mysql
|
2. 配置环境变量
1 2
| cp .env-trunk .env vi .env
|
编辑 .env 文件,设置 MySQL 配置:
1 2 3 4
| MYSQL_ROOT_PASSWORD=your_strong_password_here MYSQL_DATABASE=myapp MYSQL_USER=appuser MYSQL_PASSWORD=appuser_password
|
3. 使用 Docker Compose 部署
1 2 3 4 5
| docker compose up -d
docker-compose up -d
|
4. 验证部署
1 2 3 4 5
| docker compose ps
docker compose exec mysql mysql -uroot -p$MYSQL_ROOT_PASSWORD -e "SELECT VERSION();"
|
🐳 Docker Swarm 部署(使用 NFS)
1. 初始化 Swarm(如果尚未初始化)
2. 配置环境变量
1 2
| cp .env-trunk .env vi .env
|
配置 MySQL 和 NFS 相关参数:
1 2 3 4 5 6 7 8
| MYSQL_ROOT_PASSWORD=your_strong_password_here MYSQL_DATABASE=myapp MYSQL_USER=appuser MYSQL_PASSWORD=appuser_password
NFS_HOST=addr=192.168.1.100,nolock,soft,rw NFS_PATH=:/mnt/nfs/mysql
|
3. 部署 Stack
1
| docker stack deploy -c docker-compose.yml stack_mysql
|
4. 查看服务状态
1 2
| docker stack services stack_mysql docker service logs stack_mysql_mysql
|
📝 Docker Compose 配置示例
基础配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| version: '3.8'
services: mysql: image: mysql:8.0 container_name: mysql environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MYSQL_DATABASE: ${MYSQL_DATABASE:-myapp} MYSQL_USER: ${MYSQL_USER:-appuser} MYSQL_PASSWORD: ${MYSQL_PASSWORD} TZ: Asia/Shanghai ports: - "3306:3306" volumes: - mysql_data:/var/lib/mysql - ./conf.d:/etc/mysql/conf.d restart: unless-stopped command: --default-authentication-plugin=mysql_native_password healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}"] interval: 30s timeout: 10s retries: 3
volumes: mysql_data:
|
使用 NFS 存储(Docker Swarm)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| version: '3.8'
services: mysql: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MYSQL_DATABASE: ${MYSQL_DATABASE:-myapp} MYSQL_USER: ${MYSQL_USER:-appuser} MYSQL_PASSWORD: ${MYSQL_PASSWORD} TZ: Asia/Shanghai ports: - "3306:3306" volumes: - mysql_nfs:/var/lib/mysql - ./conf.d:/etc/mysql/conf.d restart: unless-stopped command: --default-authentication-plugin=mysql_native_password deploy: replicas: 1 placement: constraints: - node.role == manager restart_policy: condition: on-failure delay: 5s max_attempts: 3 networks: - mysql_network
volumes: mysql_nfs: driver: local driver_opts: type: nfs o: ${NFS_HOST} device: ${NFS_PATH}
networks: mysql_network: driver: overlay
|
生产环境配置(推荐)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| version: '3.8'
services: mysql: image: mysql:8.0 container_name: mysql environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MYSQL_DATABASE: ${MYSQL_DATABASE:-myapp} MYSQL_USER: ${MYSQL_USER:-appuser} MYSQL_PASSWORD: ${MYSQL_PASSWORD} TZ: Asia/Shanghai ports: - "3306:3306" volumes: - mysql_data:/var/lib/mysql - ./conf.d:/etc/mysql/conf.d - ./init:/docker-entrypoint-initdb.d restart: unless-stopped command: > --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --max_connections=200 --innodb_buffer_pool_size=1G healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}"] interval: 30s timeout: 10s retries: 3
volumes: mysql_data:
|
🔧 常用操作
连接 MySQL
1 2 3 4 5
| docker compose exec mysql mysql -uroot -p$MYSQL_ROOT_PASSWORD
docker exec -it mysql mysql -uroot -p
|
创建数据库
1
| docker compose exec mysql mysql -uroot -p$MYSQL_ROOT_PASSWORD -e "CREATE DATABASE newdb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
|
导入 SQL 文件
1
| docker compose exec -T mysql mysql -uroot -p$MYSQL_ROOT_PASSWORD myapp < backup.sql
|
导出数据库
1
| docker compose exec mysql mysqldump -uroot -p$MYSQL_ROOT_PASSWORD myapp > backup.sql
|
查看日志
1
| docker compose logs -f mysql
|
重启服务
1
| docker compose restart mysql
|
🔐 安全配置建议
1. 使用强密码
确保 .env 文件中的密码足够复杂:
1
| MYSQL_ROOT_PASSWORD=$(openssl rand -base64 32)
|
2. 限制网络访问
生产环境建议不暴露端口,或使用防火墙限制:
1 2 3 4 5 6
|
networks: - internal_network
|
3. 自定义 MySQL 配置
创建 conf.d/my.cnf:
1 2 3 4 5 6 7 8
| [mysqld] character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci max_connections=200 innodb_buffer_pool_size=1G innodb_log_file_size=256M slow_query_log=1 long_query_time=2
|
4. 初始化脚本
在 init/ 目录下放置 .sql 或 .sh 文件,容器首次启动时会自动执行。
📊 备份与恢复
自动备份脚本
创建 backup.sh:
1 2 3 4 5 6 7 8 9
| #!/bin/bash BACKUP_DIR="/backup/mysql" DATE=$(date +%Y%m%d_%H%M%S) CONTAINER_NAME="mysql"
docker exec $CONTAINER_NAME mysqldump -uroot -p$MYSQL_ROOT_PASSWORD --all-databases | gzip > $BACKUP_DIR/backup_$DATE.sql.gz
find $BACKUP_DIR -name "backup_*.sql.gz" -mtime +7 -delete
|
恢复备份
1
| gunzip < backup_20250127_120000.sql.gz | docker exec -i mysql mysql -uroot -p$MYSQL_ROOT_PASSWORD
|
🐛 常见问题
1. 连接被拒绝
- 检查密码是否正确
- 确认容器是否正常运行:
docker compose ps - 检查端口是否被占用:
netstat -tuln | grep 3306
2. 字符编码问题
确保使用 utf8mb4 字符集:
1
| ALTER DATABASE myapp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
3. 数据目录权限问题
1
| sudo chown -R 999:999 /var/lib/docker/volumes/mysql_data/_data
|
4. NFS 挂载失败
- 检查 NFS 服务器是否正常运行
- 确认 NFS 路径是否正确
- 检查防火墙设置
📚 参考资源