最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如何用Docker Compose部署MySQL?
时间:2026-09-01 20:39:49 编辑:袖梨 来源:一聚教程网
docker-compose.yml 配置需明确指定 mysql:8.0.33 版本、挂载 /var/lib/mysql 并设宿主机目录权限为 999:999、服务端与初始化脚本及连接层统一 utf8mb4 字符集,且初始化 SQL 仅在空数据目录下执行一次。
docker-compose.yml 文件配对了就能跑,但多数人卡在中文乱码、初始化不生效、数据不持久这三处。直接上可落地的解法。
mysql:8.0.33 镜像必须显式指定版本
别用 mysql:latest 或 mysql:8 —— 最新镜像的 latest 会随时间漂移,8.x 大版本间存在默认认证插件变更(mysql_native_password vs caching_sha2_password),导致客户端连不上。
- 开发/测试环境统一用
mysql:8.0.33,它稳定、文档全、兼容主流驱动 - 生产环境若需更高版本,务必验证客户端连接行为,尤其是 PHP PDO、Java JDBC 的 auth plugin 支持情况
-
command中加--default-authentication-plugin=mysql_native_password是临时补救,不是根治方案
挂载 /var/lib/mysql 才算真正持久化
只写 volumes: - ./data:/var/lib/mysql 不够,还要确保宿主机目录权限正确。MySQL 容器内以 UID 999(mysql 用户)运行,若宿主机 ./data 目录属主是 root,容器启动会失败并报错:mysqld: Can't create/write to file '/var/lib/mysql/is_writable'。
- 创建目录后立刻执行:
sudo chown -R 999:999 ./data - Mac / Windows 上 Docker Desktop 自动处理 UID 映射,但 Linux 主机必须手动设
- 不要把
/var/lib/mysql挂成只读(ro),否则初始化脚本和后续写入全失败
中文乱码:服务端 + 初始化脚本 + 连接层三者必须一致
只改 my.cnf 或只设 command 参数,都不够。乱码本质是字符集链路断在某一处。
- 服务端配置必须含两行:
character-set-server=utf8mb4和collation-server=utf8mb4_unicode_ci - 初始化 SQL 文件(如
init.sql)本身必须用 UTF-8 with BOM(或无 BOM)编码保存,Windows 记事本默认带 BOM,Linuxvim默认无 BOM,推荐用 VS Code 确认编码 - 每个 SQL 脚本开头加
SET NAMES utf8mb4;—— 这行不能省,它告诉 MySQL 当前连接用什么字符集通信 - 验证是否生效:进容器执行
mysql -uroot -p -e "SHOW VARIABLES LIKE 'character%';",确认character_set_server和collation_server均为utf8mb4
初始化 SQL 只在空数据目录下执行一次
这是最常被忽略的机制:Docker 最新镜像只在 /var/lib/mysql 为空时,才执行 /docker-entrypoint-initdb.d/*.sql。改了 SQL 想重跑?删卷再启,不是 docker-compose restart。
- 重试前先执行:
docker-compose down -v(-v删除关联的数据卷) - 若只想清空数据库但保留卷结构,可进容器执行:
mysql -uroot -p -e "DROP DATABASE IF EXISTS your_db; CREATE DATABASE your_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" - 挂载整个目录(如
./initdb:/docker-entrypoint-initdb.d)比单文件更灵活,文件按字母序执行,建议用01-create-tables.sql、02-insert-data.sql命名
MySQL 在容器里跑得稳不稳,关键不在“能不能起来”,而在“数据会不会丢”、“中文会不会变问号”、“下次重装还能不能复现”。每一步的副作用都得提前想清楚,比如 chown 999 看似小操作,漏了整条链就断。