必须挂载数据目录和配置文件:用-v将/var/lib/mysql映射到宿主机绝对路径(如/mydata/mysql),并挂载mysqld.cnf到/etc/mysql/conf.d/以设置utf8mb4;启动后需执行alter user授权远程访问;备份恢复须用docker exec调用容器内mysqldump。

直接用 docker run 启动 MySQL 容器,但必须加 -v 挂载数据目录
不挂载就等于白搭——容器重启或删除后所有数据库都会消失。MySQL 默认把数据存在 /var/lib/mysql,必须把这个路径映射到宿主机一个固定目录,比如 /mydata/mysql:
docker run -d --name mysql8 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -v /mydata/mysql:/var/lib/mysql -d mysql:8.0- 首次运行会自动初始化数据目录;如果宿主机
/mydata/mysql已存在文件,MySQL 启动会失败(报错mysqld: Can't read dir of '/var/lib/mysql/'),此时要清空该目录再试 - 别用
~或相对路径,Docker 不识别 shell 展开,必须写绝对路径
修改默认字符集为 utf8mb4,得在容器启动时传入 mysqld.cnf 配置文件
只靠环境变量改不了 server 级字符集,必须挂载自定义配置。新建 mysqld.cnf 文件内容如下:
[mysqld] character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci skip-character-set-client-handshake [client] default-character-set=utf8mb4
然后启动时用 -v 挂载进去,并通过 --defaults-file 指定(注意路径权限):
docker run -d --name mysql8 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -v /mydata/mysql:/var/lib/mysql -v $(pwd)/mysqld.cnf:/etc/mysql/conf.d/mysqld.cnf:ro -d mysql:8.0- 挂载位置必须是
/etc/mysql/conf.d/下的.cnf文件,MySQL 8 才会自动加载;放在/etc/mysql/my.cnf反而可能被忽略 - 容器内 MySQL 进程以
mysql用户运行,所以mysqld.cnf文件宿主机权限不能是 root-only(如 600),建议设为 644
连接不上?检查 bind-address 和 host 权限是否放开
MySQL 容器默认只监听 127.0.0.1,外部连不上。解决方法不是改 bind-address(Docker 网络模型下不适用),而是确保 root 用户允许远程连接:
- 容器启动后进容器执行:
mysql -u root -p -e "ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456'; FLUSH PRIVILEGES;" - 如果没开
%权限,客户端连时会报错:Host '172.17.0.1' is not allowed to connect to this MySQL server - Docker 默认使用 bridge 网络,宿主机访问用
127.0.0.1:3306,其他容器访问用服务名(如mysql8:3306),不需要额外开bind-address
备份和恢复必须进容器操作,mysqldump 不在宿主机上
别在宿主机装 MySQL 客户端去连容器 dump 数据——版本不一致可能出错,且无法保证事务一致性。正确做法是用容器自带的 mysqldump:
- 备份:
docker exec mysql8 mysqldump -u root -p123456 --all-databases > backup.sql - 恢复:
docker exec -i mysql8 mysql -u root -p123456 - 注意密码紧贴
-p之间不能有空格,否则会被当用户名处理,报错:Access denied for user 'root'@'localhost' - 如果备份文件大,建议先
docker cp到宿主机再压缩,避免管道阻塞或超时
'root'@'%' 导致应用连不上——这两点不排查清楚,其他配置都白做。










