一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

如何用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:latestmysql:8 —— 最新镜像的 latest 会随时间漂移,8.x 大版本间存在默认认证插件变更(mysql_native_password vs caching_sha2_password),导致客户端连不上。

  1. 开发/测试环境统一用 mysql:8.0.33,它稳定、文档全、兼容主流驱动
  2. 生产环境若需更高版本,务必验证客户端连接行为,尤其是 PHP PDO、Java JDBC 的 auth plugin 支持情况
  3. 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'

  1. 创建目录后立刻执行:sudo chown -R 999:999 ./data
  2. Mac / Windows 上 Docker Desktop 自动处理 UID 映射,但 Linux 主机必须手动设
  3. 不要把 /var/lib/mysql 挂成只读(ro),否则初始化脚本和后续写入全失败

中文乱码:服务端 + 初始化脚本 + 连接层三者必须一致

只改 my.cnf 或只设 command 参数,都不够。乱码本质是字符集链路断在某一处。

  1. 服务端配置必须含两行:character-set-server=utf8mb4collation-server=utf8mb4_unicode_ci
  2. 初始化 SQL 文件(如 init.sql)本身必须用 UTF-8 with BOM(或无 BOM)编码保存,Windows 记事本默认带 BOM,Linux vim 默认无 BOM,推荐用 VS Code 确认编码
  3. 每个 SQL 脚本开头加 SET NAMES utf8mb4; —— 这行不能省,它告诉 MySQL 当前连接用什么字符集通信
  4. 验证是否生效:进容器执行 mysql -uroot -p -e "SHOW VARIABLES LIKE 'character%';",确认 character_set_servercollation_server 均为 utf8mb4

初始化 SQL 只在空数据目录下执行一次

这是最常被忽略的机制:Docker 最新镜像只在 /var/lib/mysql 为空时,才执行 /docker-entrypoint-initdb.d/*.sql。改了 SQL 想重跑?删卷再启,不是 docker-compose restart

  1. 重试前先执行:docker-compose down -v-v 删除关联的数据卷)
  2. 若只想清空数据库但保留卷结构,可进容器执行:mysql -uroot -p -e "DROP DATABASE IF EXISTS your_db; CREATE DATABASE your_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
  3. 挂载整个目录(如 ./initdb:/docker-entrypoint-initdb.d)比单文件更灵活,文件按字母序执行,建议用 01-create-tables.sql02-insert-data.sql 命名

MySQL 在容器里跑得稳不稳,关键不在“能不能起来”,而在“数据会不会丢”、“中文会不会变问号”、“下次重装还能不能复现”。每一步的副作用都得提前想清楚,比如 chown 999 看似小操作,漏了整条链就断。

热门栏目