laravel sail Operation CREATE USER failed for 'root'@'%'
mysql-1 | 2024-07-07T13:16:49.718522Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.32' socket: '/var/lib/mysql/mysql.sock' port: 0 MySQL Community Server - GPL.
mysql-1 | Warning: Unable to load '/usr/share/zoneinfo/iso3166.tab' as time zone. Skipping it.
mysql-1 | Warning: Unable to load '/usr/share/zoneinfo/leapseconds' as time zone. Skipping it.
mysql-1 | Warning: Unable to load '/usr/share/zoneinfo/tzdata.zi' as time zone. Skipping it.
mysql-1 | Warning: Unable to load '/usr/share/zoneinfo/zone.tab' as time zone. Skipping it.
mysql-1 | Warning: Unable to load '/usr/share/zoneinfo/zone1970.tab' as time zone. Skipping it.
mysql-1 | ERROR 1396 (HY000) at line 1: Operation CREATE USER failed for 'root'@'%'
问题的原因:
- MySQL 安全策略: MySQL 默认的安全策略限制了 root 用户从远程连接。这是为了增强数据库的安全性。
- Docker 网络: 在 Docker 环境中,即使 Laravel 和 MySQL 在同一个 Docker 网络中,它们也被视为”远程”连接。
- MySQL 配置: 在你的 docker-compose.yml 文件中,有这样一行配置:
MYSQL_ROOT_HOST: "%"
这本应允许 root 用户从任何主机连接,但在某些 MySQL 版本中,这个设置可能不会完全覆盖默认的安全策略。 - 用户创建过程: 当 MySQL 容器首次启动时,它会根据环境变量创建用户。对于非 root 用户(如 ‘sail’ 或 ‘test’),它会正确地设置允许从任何主机连接的权限。
- root 用户的特殊处理: root 用户在 MySQL 中有特殊地位,其权限和连接能力受到额外的安全限制。即使通过环境变量设置了密码,一些默认的安全设置可能仍然阻止它从”远程”连接。
- 错误处理: 当使用 root 用户尝试连接时,可能会遇到权限错误,而这个错误可能没有被清晰地反映在应用程序的错误消息中。
- 非 root 用户的行为: 当使用非 root 用户(如 ‘test’)时,这个用户是在容器启动时新创建的,没有额外的安全限制,因此可以正常连接。
解决方案:
使用非 root 用户(如 ‘sail’ 或 ‘test’)
如果确实需要使用 root 用户,可能需要额外的 MySQL 配置或在容器启动后手动修改 root 用户的权限。
在生产环境中,始终应该使用具有最小必要权限的专门用户,而不是 root 用户。
本作品采用《CC 协议》,转载必须注明作者和本文链接