MySQL 8.0 Docker 容器持久化数据的核心是将容器内的/var/lib/mysql 目录挂载到宿主机绝对路径。若不挂载,容器删除后数据彻底丢失;若挂载但权限错误(需 UID 999),容器将卡在初始化阶段。
先说结论:必须使用 bind mount 将/var/lib/mysql 映射到宿主机目录,且该目录属主必须设为 999:999。
- 适合:生产环境需保留数据、方便备份迁移的场景
- 先准备:宿主机提前创建目录并执行 chown -R 999:999
- 验收:容器启动后宿主机目录出现 ibdata1 等文件且无权限报错
命令速用版
以下命令创建目录、修正权限并启动容器,数据将保存在宿主机/data/mysql8 路径:
sudo mkdir -p /data/mysql8
sudo chown -R 999:999 /data/mysql8
docker run -d `--name` mysql8 -v /data/mysql8:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=YourStrongPassword -p 3306:3306 `--restart` unless-stopped mysql:8.0为什么会这样
容器默认文件系统是临时的,删除容器即删除数据。MySQL 8.0 镜像硬编码数据路径为/var/lib/mysql,且容器内进程以 UID 999 用户运行。若宿主机目录属主为 root,MySQL 进程无权写入,导致初始化失败或反复重启。
分步处理
1. 创建宿主机目录:执行 sudo mkdir -p /data/mysql8,确保路径存在。
2. 修正目录权限:执行 sudo chown -R 999:999 /data/mysql8,不能用 chmod 777。
3. 启动容器挂载:使用-v 参数将宿主机目录映射到/var/lib/mysql。
4. 配置文件挂载:若有自定义配置,挂载到/etc/mysql/conf.d/且文件后缀为.cnf,内容含 [mysqld] 段。
怎么验证是否生效
1. 检查宿主机文件:执行 ls -l /data/mysql8,确认存在 ibdata1、mysql 文件夹等数据文件。
2. 检查容器日志:执行 docker logs mysql8,确认无 Permission denied 或 Can't open the mysql.plugin table 报错。
3. 验证数据持久性:删除容器 docker rm -f mysql8 后重新启动,确认数据仍存在。
常见坑
1. 环境变量不生效:若挂载目录非空(有旧数据),MYSQL_ROOT_PASSWORD 等环境变量会被忽略,仅首次初始化有效。
2. 挂载路径错误:不能挂载到/etc/mysql 或空父目录,必须是/var/lib/mysql。
3. 配置文件失效:自定义 my.cnf 若直接覆盖/etc/mysql/my.cnf 可能漏掉关键项,推荐放在/etc/mysql/conf.d/下。
常见问题
为什么修改 MYSQL_ROOT_PASSWORD 后密码还是旧的?
因为挂载的宿主机目录非空,MySQL 跳过了初始化流程。需清空目录后重启容器。
容器卡在 Initializing database 怎么办?
通常是宿主机目录权限不对。检查是否执行了 chown -R 999:999,并确保目录为空。
配置文件挂载后不生效是什么原因?
检查文件是否在/etc/mysql/conf.d/目录下,后缀是否为.cnf,且内容是否包含 [mysqld] 段。
参考来源
- 如何在 Docker 容器中持久化存储 MySQL 8.0 的数据文件?
- 如何在 Docker 容器中快速部署带持久化存储的 MySQL 8.0?
- 怎样在 Docker 中配置 MySQL 8.0 实现数据持久化与自动备份?
- Docker 快速安装 MySQL 8.0 完整教程 (附配置优化 + 远程连接)