1. 为什么选择Docker部署MySQL?
在数据库部署领域,Docker已经成为现代开发者的首选方案。相比传统安装方式,Docker容器化部署MySQL具有几个不可替代的优势:
- 环境一致性:消除"在我机器上能跑"的问题,开发、测试、生产环境完全一致
- 秒级启停:容器启动仅需2-3秒,而传统服务启动需要分钟级等待
- 资源隔离:每个MySQL实例独立运行,互不干扰
- 版本切换:通过更换镜像标签即可切换MySQL 5.7/8.0等不同版本
我最近为一个电商项目搭建测试环境时,需要在同一台服务器部署三个不同版本的MySQL实例。传统方式需要处理复杂的多实例配置,而用Docker只需三条命令就搞定了:
docker run --name mysql57 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7 docker run --name mysql80 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:8.0 docker run --name mysql-latest -e MYSQL_ROOT_PASSWORD=123456 -d mysql:latest2. 准备工作与环境配置
2.1 Docker环境检查
在开始前,建议先确认Docker环境状态。新手常犯的错误是直接运行MySQL容器而忽略了基础环境检查:
# 检查Docker服务状态 systemctl status docker # 查看Docker版本(要求18.06+) docker --version # 测试基础容器运行 docker run hello-world注意:如果遇到权限问题,需要将当前用户加入docker用户组:
sudo usermod -aG docker $USER newgrp docker
2.2 镜像源优化
国内用户建议配置镜像加速器,否则拉取MySQL官方镜像速度可能很慢。这是我常用的阿里云镜像配置:
sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://[your-id].mirror.aliyuncs.com"] } EOF sudo systemctl daemon-reload sudo systemctl restart docker3. MySQL容器部署实战
3.1 基础运行命令
最简启动命令如下,但生产环境绝不能这样使用:
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag推荐的生产级启动命令应包含以下关键参数:
docker run -d \ --name mysql8-primary \ -p 3306:3306 \ -v /data/mysql/conf:/etc/mysql/conf.d \ -v /data/mysql/data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=ComplexPwd@2023 \ -e MYSQL_DATABASE=app_db \ -e MYSQL_USER=app_user \ -e MYSQL_PASSWORD=UserPwd@123 \ --restart=unless-stopped \ --memory=2g \ --cpus=1 \ mysql:8.0 \ --character-set-server=utf8mb4 \ --collation-server=utf8mb4_unicode_ci参数说明:
-v挂载配置和数据目录,避免容器销毁数据丢失--restart设置自动重启策略--memory限制容器内存使用- 末尾追加MySQL服务参数设置字符集
3.2 配置文件定制
建议通过挂载方式自定义MySQL配置。创建/data/mysql/conf/my-custom.cnf:
[mysqld] max_connections=200 innodb_buffer_pool_size=1G innodb_log_file_size=256M skip-name-resolve default-time-zone='+8:00' [client] default-character-set=utf8mb44. 容器化MySQL管理技巧
4.1 日常运维命令
# 查看运行日志 docker logs -f mysql8-primary # 进入容器执行命令 docker exec -it mysql8-primary mysql -uroot -p # 备份数据库(无需进入容器) docker exec mysql8-primary sh -c 'exec mysqldump --all-databases -uroot -p"$MYSQL_ROOT_PASSWORD"' > all-databases.sql # 性能监控 docker stats mysql8-primary4.2 数据持久化验证
验证数据卷是否生效的实用方法:
# 在容器内创建测试数据 docker exec -it mysql8-primary mysql -uroot -p -e "CREATE DATABASE persistence_test;" # 删除容器 docker stop mysql8-primary docker rm mysql8-primary # 重新创建容器(使用相同数据卷) docker run --name mysql8-new -v /data/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=ComplexPwd@2023 -d mysql:8.0 # 检查数据是否存在 docker exec -it mysql8-new mysql -uroot -p -e "SHOW DATABASES;"5. 常见问题排错指南
5.1 启动失败排查流程
查看容器日志:
docker logs mysql-container常见错误1:端口冲突
Error starting userland proxy: listen tcp4 0.0.0.0:3306: bind: address already in use解决方案:
sudo lsof -i :3306 # 找出占用进程 kill -9 <PID> # 终止冲突进程 或改用其他端口 -p 3307:3306常见错误2:权限问题
[ERROR] [Entrypoint]: mysqld failed while attempting to check config解决方案:
chown -R 999:999 /data/mysql/data # MySQL容器内用户UID为999
5.2 性能优化建议
内存分配:
- 容器内存应大于
innodb_buffer_pool_size+ 其他组件需求 - 建议预留20%缓冲
- 容器内存应大于
IO优化:
docker run ... --mount type=volume,dst=/var/lib/mysql,volume-driver=local,volume-opt=type=none,volume-opt=o=bind,volume-opt=device=/ssd/mysql-data ...网络配置:
--network my-bridge-network # 使用自定义网络
6. 高级部署方案
6.1 主从复制配置
主库启动命令:
docker run --name=mysql-master \ -e MYSQL_ROOT_PASSWORD=masterpass \ -e MYSQL_REPLICATION_USER=repl \ -e MYSQL_REPLICATION_PASSWORD=replpass \ -v /path/to/master/conf:/etc/mysql/conf.d \ -d mysql:8.0 \ --server-id=1 \ --log-bin=mysql-bin \ --binlog-format=ROW从库启动命令:
docker run --name=mysql-slave \ --link mysql-master:master \ -e MYSQL_ROOT_PASSWORD=slavepass \ -e MYSQL_REPLICATION_USER=repl \ -e MYSQL_REPLICATION_PASSWORD=replpass \ -d mysql:8.0 \ --server-id=26.2 使用Docker Compose编排
创建docker-compose.yml:
version: '3.8' services: mysql: image: mysql:8.0 container_name: mysql8-compose environment: MYSQL_ROOT_PASSWORD: rootpass MYSQL_DATABASE: app_db MYSQL_USER: app_user MYSQL_PASSWORD: userpass volumes: - mysql_data:/var/lib/mysql - ./conf:/etc/mysql/conf.d ports: - "3306:3306" deploy: resources: limits: cpus: '1' memory: 2G healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] interval: 5s timeout: 10s retries: 5 volumes: mysql_data:启动命令:
docker-compose up -d