必须手动隔离端口、数据目录和容器名:端口需显式映射不同宿主机端口(如3307:3306),数据卷路径须独立并提前赋权(chown -r 999:999),容器名不可重复;mysql 8.0+需配置mysql_native_password认证插件及utf8mb4字符集与时区(tz=asia/shanghai)。

能,但必须手动隔离三件事:端口、数据目录、容器名。缺一不可,否则轻则连接错库,重则数据覆盖。
端口映射必须显式指定不同宿主机端口
MySQL容器默认监听3306,但宿主机端口只能被一个进程占用。直接跑两个docker run -p 3306:3306会失败,第二个容器启动时提示Bind for 0.0.0.0:3306 failed: port is already allocated。
- 每个实例用不同宿主机端口,比如
3307:3306、3308:3306、3309:3306 - 避免使用
3306以外的“常见端口”如3307——某些旧版客户端(如部分Navicat版本)默认只连3306,需手动改端口 - Mac或Windows上用
localhost:3307访问;Linux宿主机内若需容器间通信,用容器名+默认3306(如mysql-80:3306)
数据卷路径不能复用,且需提前创建并赋权
挂载同一目录(如都用-v /data/mysql:/var/lib/mysql)会导致两个实例争抢InnoDB文件,大概率启动失败,日志里出现InnoDB: Unable to lock ./ibdata1 error或mysqld: Can't start server: Bind on TCP/IP port.。
- 每个版本单独建目录:
/data/mysql-57、/data/mysql-84、/data/mysql-innovation - 创建后执行
chown -R 999:999 /data/mysql-*(MySQL容器默认以uid=999运行),否则容器启动卡在Initializing database - 首次启动后,目录下会生成
ibdata1、mysql等文件,直接删掉再启容器会重新初始化,丢数据
MySQL 8.0+ 默认认证插件不兼容老客户端
用mysql:8.0及以上镜像启动后,Navicat、DBeaver甚至部分PHP PDO连接常报错:Client does not support authentication protocol requested by server 或 Plugin caching_sha2_password could not be loaded。
- 根本原因是MySQL 8.0+默认用
caching_sha2_password,而旧客户端没加载对应so文件 - 最稳方案:启动时加参数
--default-authentication-plugin=mysql_native_password - 或者挂载自定义
my.cnf,在[mysqld]段写default_authentication_plugin=mysql_native_password - 注意:该设置只影响新创建用户,root密码仍需用
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'xxx';重置
别忽略时区和字符集,否则开发环境和生产环境行为不一致
MySQL容器默认时区是UTC,NOW()返回时间比东八区慢8小时;默认字符集是latin1,存中文变???。
- 启动时加环境变量:
-e TZ=Asia/Shanghai和-e MYSQL_INITDB_SKIP_TZINFO=1(跳过时区表初始化,避免权限问题) - 字符集统一用
utf8mb4:加参数--character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci - 如果挂载
my.cnf,确保[client]和[mysql]段也设default-character-set=utf8mb4,否则命令行mysql工具仍用latin1
真正麻烦的不是启动几个容器,而是每次拉新版本镜像后,得重新核对default_authentication_plugin是否还生效、mysql-files目录是否要额外挂载(MySQL 8.0.26+要求)、以及Innovation版是否已弃用某参数——这些细节不会报错,但会让连接或导入莫名失败。











