MySQL容器挂载宿主机目录启动失败主因是权限(需chown 999:999)、配置加载路径错误(conf.d下生效,my.cnf被忽略)、datadir未显式声明及挂载路径层级不匹配。

直接挂载宿主机目录运行 mysql:5.7 容器是可行的,但不加处理大概率启动失败或数据不可读——核心问题不在命令写没写对,而在权限、路径映射逻辑和配置加载顺序这三处。
为什么容器启动后立刻退出或报 Can't start server: Bind on unix socket: Permission denied
MySQL 官方镜像 mysql:5.7 以 UID/GID 999 运行 mysqld 进程,不是 root。宿主机挂载目录若属主不是 999:999,容器内进程就无法读写 /var/lib/mysql。
- 必须执行
chown -R 999:999 /path/to/your/data,不只是data目录,如果还挂了conf.d或logs,也要一并改 -
chmod -R 700 /path/to/your/data不是可选项,MySQL 5.7 对目录权限敏感,755可能被拒绝初始化 - 不要用
--privileged=true掩盖权限问题,它开的是全量 cap,反而增加攻击面
-v /host/conf:/etc/mysql/conf.d 和 -v /host/my.cnf:/etc/mysql/my.cnf 效果完全不同
Docker MySQL 镜像默认只加载 /etc/mysql/conf.d/*.cnf,/etc/mysql/my.cnf 被忽略(除非你显式用 --defaults-file 指定)。
- 正确做法:把配置文件放在宿主机
/opt/mysql/conf/my.cnf,然后挂载为-v /opt/mysql/conf:/etc/mysql/conf.d,这样容器内实际路径是/etc/mysql/conf.d/my.cnf,会被自动加载 - 错误做法:挂成
-v /opt/mysql/conf/my.cnf:/etc/mysql/my.cnf,该文件不会生效,lower_case_table_names、character-set-server等关键项全失效 - 配置里必须显式声明
datadir = /var/lib/mysql,否则某些系统下会误读为默认路径导致初始化失败
迁移旧 MySQL 5.7 数据前必须停服务并校验文件完整性
不能在原库运行时直接 cp 或 rsync 数据目录,InnoDB 的 ib_logfile* 和未刷盘的 buffer pool 会导致容器内启动时崩溃。
- 先停原服务:
systemctl stop mysql或service mysqld stop - 确认
datadir位置:mysql -uroot -p -e "SHOW VARIABLES LIKE 'datadir';" - 打包保留权限:
tar -czf mysql-data-backup.tar.gz -C /var/lib/ mysql(注意末尾无斜杠) - 解压后立即
chown -R 999:999,再启动容器;否则日志里会出现Operating system error number 13
最容易被跳过的点是:挂载路径里的层级必须严格匹配容器内预期路径,比如 /var/lib/mysql 是固定目标,你挂 /data/mysql 就行,但挂 /data/mysql/(末尾带斜杠)有时会触发 Docker 的隐式行为,导致目录嵌套一层;另外,conf.d 目录下多个 .cnf 文件按字母序加载,冲突参数以后者为准——这点在调试字符集或 SQL mode 时特别容易踩坑。











