启动容器时通过环境变量设置 MySQL root 密码
MySQL 官方镜像(
mysql:8.0、
mysql:5.7)支持在首次启动时用
MYSQL_ROOT_PASSWORD环境变量自动初始化 root 密码。这是最安全、最推荐的方式,避免密码硬编码进命令或配置文件。 该变量仅在容器第一次初始化数据库时生效;如果容器已存在数据卷(
/var/lib/mysql非空),环境变量会被忽略 必须配合
-e MYSQL_ROOT_PASSWORD=your_secure_password使用,不能只写
-e MYSQL_ROOT_PASSWORD若同时设置了
MYSQL_ALLOW_EMPTY_PASSWORD=yes,则
MYSQL_ROOT_PASSWORD会被跳过
docker run -d \ --name mysql-dev \ -e MYSQL_ROOT_PASSWORD=MyPass123! \ -p 3306:3306 \ -v /mydata/mysql:/var/lib/mysql \ -d mysql:8.0
连接后用 SQL 命令修改 root 密码(适用于已有容器)
如果容器已运行且未设密码,或者想更换密码,需先以无密码方式进入 MySQL,再执行
ALTER USER。注意:MySQL 8.0+ 不再支持
SET PASSWORD旧语法,且默认认证插件是
caching_sha2_password。 先确认容器是否允许本地无密码登录:检查是否启用了
skip-grant-tables(不推荐)或是否用
MYSQL_ALLOW_EMPTY_PASSWORD=yes启动 连接后执行的语句必须指定
BY子句,并显式指定认证插件(尤其在 8.0+) 修改后需执行
FLUSH PRIVILEGES,否则新密码不生效
docker exec -it mysql-dev mysql -uroot -p # 输入当前密码(若已设)或直接回车(若为空) mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password BY 'NewPass456!'; mysql> ALTER USER 'root'@'%' IDENTIFIED WITH caching_sha2_password BY 'NewPass456!'; mysql> FLUSH PRIVILEGES;
使用自定义配置文件 + 初始化脚本绕过环境变量限制
当需要更细粒度控制(如禁用密码过期、调整密码策略、创建其他用户),可挂载
my.cnf并提供
/docker-entrypoint-initdb.d/下的 SQL 或 Shell 脚本。该目录下的脚本只在首次初始化时执行。 脚本必须是
.sql、
.sql.gz或
.sh后缀,且有可执行权限(对 .sh) 脚本中不能用
mysql -uroot -p...连接——此时 root 密码尚未设置,应直接用
mysql -uroot(无密码) 若镜像版本 ≥ 8.0.21,
validate_password插件默认启用,脚本中需先
SET GLOBAL validate_password.policy = LOW;再设简单密码
# init.sql 示例: SET GLOBAL validate_password.policy = LOW; ALTER USER 'root'@'localhost' IDENTIFIED BY 'dev123'; CREATE USER 'appuser'@'%' IDENTIFIED BY 'app789'; GRANT SELECT,INSERT ON mydb.* TO 'appuser'@'%';
常见错误:连接被拒绝或认证失败
即使设了密码,仍连不上,大概率是主机绑定或认证插件不匹配。MySQL 容器默认只监听
localhost,外部访问需确保
bind-address为
0.0.0.0(官方镜像默认已是),并开放
'root'@'%'权限。 错误信息
Access denied for user 'root'@'172.17.0.1':说明客户端从 Docker 网络 IP 连入,但 root 只允许
'root'@'localhost'错误信息
Client does not support authentication protocol requested by server:客户端(如老版 MySQL CLI 或某些 ORM)不支持
caching_sha2_password,需改用
mysql_native_password忘记密码且容器无法重启?别删数据卷——可临时加
--skip-grant-tables启动,但必须挂载自定义配置并禁用网络,操作风险高
最稳妥的做法:每次新建容器都用
MYSQL_ROOT_PASSWORD,生产环境额外配
MYSQL_ROOT_HOST=%允许远程 root(仅测试环境),并立即用 SQL 收紧权限。
