必须挂载/var/lib/mysql到nas共享文件夹,否则容器删除后数据彻底丢失;挂载路径必须是/var/lib/mysql且需设nas目录权限为users组可读写,同时挂载custom.cnf至/etc/mysql/conf.d以启用远程访问和utf8mb4。

必须挂载 /var/lib/mysql 到 NAS 共享文件夹,否则容器一删,数据彻底丢失——这不是警告,是事实。
挂载路径必须是 /var/lib/mysql,不能是其他任何路径
MySQL 8.0 官方镜像硬编码所有数据写入 /var/lib/mysql:ibdata1、redo log、每个表的 .ibd 文件全在里面。挂错路径(比如映射到 /data 或 /mysql)会导致容器反复重启,日志只报 error: database is uninitialized。
- 正确做法:在 DSM 图形界面「存储空间设置」中,把 NAS 路径(如
/volume1/docker/mysql8/data)映射到容器内/var/lib/mysql - 错误示例:映射到
/etc/mysql(配置目录)、/root(权限混乱)、空目录(初始化失败) - 权限问题常被忽略:NAS 上该文件夹属
root用户,但 MySQL 进程以mysql用户运行;建议在 File Station 中右键文件夹 →「属性」→「权限」→ 勾选「应用至所有子文件夹和文件」→ 将「读取/写入」权限赋予users群组
MYSQL_ROOT_PASSWORD 是唯一强制环境变量,且有三重限制
不设这个变量,容器直接退出;设了但不符合规则,一样失败,日志还是那句 error: database is uninitialized。
- 不能为空:填空格、空字符串、只敲回车,都算空
- 不能含
$、@、#、&等 shell 特殊字符——DSM 界面会提前截断或转义,导致实际传给容器的是残缺密码 - 不能太弱:MySQL 8.0 默认启用
validate_password插件,纯数字(如123456)、常见单词(如password)会被拒绝初始化
端口必须手动指定,别信「自动分配」
DSM 勾选「自动」后,大概率分到 32768–32775 这类高位端口。Navicat、Java 应用默认连 :3306,根本找不到服务。
- 标准方案:NAS 端口填
3306,容器端口填3306(前提是没装套件中心的 MariaDB) - 冲突时换端口:NAS 端口填
3307,容器端口仍填3306;客户端连接地址写成nas-ip:3307 - 别同时映射多个端口(如
3306:3306和3307:3306)——容器只监听一个内部端口,多映射无意义,还可能触发 DSM 端口校验失败
远程访问和 utf8mb4 必须靠 custom.cnf 挂载到 /etc/mysql/conf.d
DSM 图形界面不提供编辑配置入口,而 MySQL 8.0 默认禁用远程访问、默认字符集是 latin1。跳过这步,Navicat 连上也插不了中文,或者直接被拒绝连接。
- 先在 NAS 创建目录:
/volume1/docker/mysql8/conf,里面放custom.cnf - 文件内容至少包含:
[mysqld] character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci bind-address=0.0.0.0
- 挂载时,把
/volume1/docker/mysql8/conf映射到容器内/etc/mysql/conf.d(不是/etc/mysql/my.cnf!后者是只读的,改了也无效) - 首次登录后执行
SHOW VARIABLES LIKE 'char%';,确认输出全是utf8mb4;再执行SELECT Host,User,plugin FROM mysql.user;,确认有'admin'@'%'且 plugin 是mysql_native_password
最常被跳过的其实是权限和字符集两步:数据能存,但连不上;连得上,但中文变问号;连得上也存得进中文,但某天容器重建后发现所有配置又回退了——因为 /etc/mysql/conf.d 没挂载,每次都是镜像自带的默认配置在起作用。











