必须挂载/var/lib/mysql到宿主机绝对路径并设属主999:999,否则容器删除数据丢失;挂载目录须预先创建、不可为空父目录或复用其他数据目录,且仅在为空时生效环境变量初始化。

必须挂载 /var/lib/mysql 到宿主机绝对路径
容器删了数据就没了,这是默认行为。唯一能保住数据的方式,就是把 /var/lib/mysql 映射到宿主机一个**已创建且权限正确**的目录。不能挂到空父目录(比如只建了 /data 却挂 /data/mysql8),也不能复用其他程序的数据目录。
- 先手动创建目录:
sudo mkdir -p /data/mysql8 - 必须改属主:
sudo chown -R 999:999 /data/mysql8(不是chmod 777) - 如果目录里已有旧数据,确保是 MySQL 8.0 同版本生成的,否则启动时会拒绝加载
- 常见错误日志:
mysqld: Can't open the mysql.plugin table或反复打印Initializing database
docker run 命令里怎么写挂载和初始化参数
挂载只是第一步,还得让容器知道怎么初始化、怎么设密码、要不要建库。这些全靠环境变量驱动,但只在 /data/mysql8 为空时生效。
-
-v /data/mysql8:/var/lib/mysql是必须项,位置不能错 -
-e MYSQL_ROOT_PASSWORD=your_pass设 root 密码(密码需含大小写字母+数字+符号,至少12位) - 可选:
-e MYSQL_DATABASE=app_db和-e MYSQL_USER=app_user+-e MYSQL_PASSWORD=user_pass,会在初始化时自动建库建用户 - 加
--restart unless-stopped,避免宿主机重启后服务掉线 - 端口映射别漏:
-p 3306:3306,如需限制访问可写成-p 127.0.0.1:3306:3306
配置文件放哪才被 MySQL 8.0 容器读到
MySQL 8.0 容器按固定顺序加载配置:/etc/mysql/my.cnf → /etc/mysql/conf.d/*.cnf → /etc/mysql/mysql.conf.d/*.cnf。挂错位置或格式不对,配置就等于没写。
- 最稳妥方式:挂整个
conf.d目录,例如-v /host/conf.d:/etc/mysql/conf.d - 宿主机上放
/host/conf.d/01-charset.cnf,内容必须以[mysqld]开头 - 必须包含这两行:
default_authentication_plugin=mysql_native_password(否则 Navicat 或老 JDBC 连不上)、default-time_zone='+8:00' - 别直接挂
my.cnf到/etc/mysql/my.cnf——它会覆盖全部默认配置,容易漏掉关键项
为什么改了密码或配置后重启还是旧状态
因为 MySQL 8.0 初始化只做一次。只要 /data/mysql8 目录非空,后续所有 MYSQL_* 环境变量和初始化 SQL 都会被跳过,容器直接加载现有数据。
- 想重置,得清空
/data/mysql8再启动(注意备份) - 初始化 SQL 要放
/docker-entrypoint-initdb.d/下,且必须是.sql或.sh文件,容器首次启动时执行 - 修改配置后要重启容器,但仅挂载配置目录不重启,新配置不会生效
- 时间、字符集、认证插件这些一旦初始化完成,就得进容器用 SQL 改,不能靠环境变量
/var/lib/mysql 挂载路径、UID 999 权限、配置文件命名与段落开头这三处最容易出错,检查日志第一眼就盯这三项。











