MySQL容器必须挂载/var/lib/mysql目录,否则重启或删除后数据丢失;推荐用命名卷docker run -v mysql-data:/var/lib/mysql;初始化SQL脚本须放/docker-entrypoint-initdb.d/;配置文件应置于/etc/mysql/conf.d/并只读挂载;备份应停容器后直接操作Volume路径。

MySQL容器启动时必须挂载/var/lib/mysql目录
不挂载这个路径,容器重启或删除后所有数据立刻清空——这是最常踩的坑。Docker默认使用临时文件系统,mysqld写入的数据全在容器层,一删就丢。
实操建议:
- 用命名卷最稳妥:
docker run -v mysql-data:/var/lib/mysql,Docker自动管理路径和权限 - 若用宿主机目录(如
/opt/mysql/data),务必提前创建并赋权:chown -R 999:999 /opt/mysql/data(MySQL官方镜像默认以用户mysql(UID 999)运行) - 切勿挂载父目录(如
/var/lib),会导致MySQL无法初始化或启动失败
初始化SQL脚本必须放在/docker-entrypoint-initdb.d/
只挂载数据目录还不够:首次启动时没数据,但你希望自动建库、建表、导入初始数据。官方镜像只认这个固定路径下的.sql或.sh文件。
常见错误现象:
- 脚本放错位置(如
/init.sql),容器日志显示“Skipping initialization” - 脚本有语法错误,MySQL启动卡住,
docker logs里能看到ERROR 1064等提示 - 挂载了已有数据卷,镜像会跳过整个初始化流程——这是设计行为,不是bug
示例命令:docker run -v ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro -v mysql-data:/var/lib/mysql mysql:8.0
配置文件挂载要避开mysqld启动参数冲突
直接改/etc/mysql/my.cnf容易被启动命令覆盖。官方镜像优先读取docker run传入的--character-set-server=utf8mb4这类参数,其次才是配置文件。
正确做法:
- 把自定义配置放到
/etc/mysql/conf.d/下(如/etc/mysql/conf.d/custom.cnf),该目录被默认包含 - 挂载时用
:ro只读,避免容器内进程误删或覆盖:-v ./custom.cnf:/etc/mysql/conf.d/custom.cnf:ro - 注意字符集配置必须成对出现:
character-set-server=utf8mb4+collation-server=utf8mb4_0900_ai_ci,否则客户端连接可能报Unknown character set
备份与迁移必须绕过容器直接操作Volume内容
别在运行中的MySQL容器里执行mysqldump再重定向到宿主机——网络、权限、路径都容易出问题。Volume本质是宿主机上的目录或块设备,直接操作更可靠。
实操要点:
- 查卷位置:
docker volume inspect mysql-data,看Mountpoint字段 - 停掉容器再备份:
docker stop mysql-container && tar -czf mysql-backup.tar.gz -C /var/lib/docker/volumes/mysql-data/_data . - 恢复时先清空目标卷目录,再解压,最后确保UID/GID仍是999
- 若用
mysqldump,进容器导出后用docker cp拷出,比挂载临时目录更干净
真正麻烦的是权限和SELinux——尤其在CentOS/RHEL上,chcon -R system_u:object_r:container_file_t:s0可能得跟上,否则容器启动时拒绝访问Volume。


















