必须挂载/var/lib/mysql到群晖共享文件夹,因mysql所有数据文件默认写入该路径,不挂载则容器删除后数据彻底丢失;映射错路径、权限不足或未设mysql_root_password均导致初始化失败。

数据不挂载到 NAS 本地路径,容器一删,库就没了——必须挂 /var/lib/mysql 到群晖共享文件夹。
为什么 /volume1/docker/mysql8/data 必须映射到 /var/lib/mysql
MySQL 容器内所有数据库文件(包括 ibdata1、ib_logfile、.ibd 表文件)默认全写在 /var/lib/mysql。Docker 默认用临时文件系统运行,容器停止再删,这个目录里的东西就彻底消失。群晖上持久化只有一条路:把该路径完整映射到 NAS 的实际磁盘位置,比如 /volume1/docker/mysql8/data。
- 映射错路径(比如映射到
/etc/mysql或空目录)→ 容器能启动但初始化失败,日志反复报error: database is uninitialized - 没挂载 → 数据全在容器层,重启或重装等于重装系统
- 路径权限不对(如 NAS 上该文件夹属 root,但 MySQL 进程以 mysql 用户运行)→ 容器卡在 starting 状态,
docker logs显示 permission denied
MYSQL_ROOT_PASSWORD 设置的三个硬性限制
这是唯一强制要求的环境变量,但值不是随便填的:
- 不能为空 —— 填空字符串或只填空格,容器直接退出,日志只显示
error: database is uninitialized - 不能含
$、@、#、&等 shell 特殊字符 —— DSM 图形界面会把这些字符当语法解析,导致密码截断或注入错误 - 别用纯数字或常见弱口令(如
123456)—— MySQL 8.0 默认启用 validate_password 插件,太短或太简单会被拒绝初始化
端口映射必须手动指定 NAS 端口,不能选“自动”
DSM 图形界面里如果勾选“自动分配端口”,NAS 会随机选一个高位端口(比如 32768),但你根本不知道是哪个。结果就是 Navicat、HeidiSQL 连不上,telnet 也通不过。
- 想用标准端口:NAS 端口填
3306,容器端口填3306;前提是群晖没跑其他 MySQL 或 MariaDB(比如套件中心自带的 MariaDB) - 冲突时换端口:NAS 端口填
3307,容器端口仍填3306;客户端连接时必须用host:3307 - 别映射多个端口(如同时映射 3306 和 3307)—— 容器只监听一个内部端口,多映射无意义,还可能触发 DSM 端口冲突校验
配置文件挂载必须到 /etc/mysql/conf.d,不是 /etc/mysql/my.cnf
MySQL 8.0 启动时按顺序加载配置:先读 /etc/mysql/my.cnf,再递归读 /etc/mysql/conf.d/*.cnf。官方镜像里 /etc/mysql/my.cnf 是只读的,改了也没用;而 /etc/mysql/conf.d 是空目录,专门留给用户挂自定义配置。
- 挂错位置(如挂到
/etc/mysql/my.cnf)→ 容器启动失败,报错mysqld: Can't read from file '/etc/mysql/my.cnf' - custom.cnf 文件里漏掉
[mysqld]段 → 字符集设置无效,SHOW VARIABLES LIKE 'character_set_server'仍是latin1 - 没加
bind-address = 0.0.0.0→ 默认只监听127.0.0.1,局域网其他设备连不上
真正麻烦的不是启动,而是第一次登录后那几条 SQL —— CREATE USER、GRANT、FLUSH PRIVILEGES 缺一不可,而且 caching_sha2_password 认证方式得单独处理,否则旧版客户端连都连不上。











