You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker部署Rails 6连接MySQL报错:Access denied for user 'user'@'%'

Rails 6 Docker部署:MySQL连接权限问题排查与解决

核心问题分析

你遇到的Mysql2::Error::ConnectionError: Access denied for user 'user'@'%' to database 'db_production'错误,核心大概率是数据库用户权限不足或配置不一致导致的,结合Ubuntu版本差异、手动连接正常但db:create失败的现象,以下是具体排查和解决步骤:


解决步骤

1. 检查数据库用户权限(最可能原因)

MySQL官方镜像通过MYSQL_USER创建的用户,默认仅拥有登录权限,没有创建数据库的权限——这就是为什么你能手动连接数据库,但执行db:create会报错的原因(db:create需要用户具备CREATE DATABASE权限)。

临时验证方法:

进入MySQL容器,给用户授予创建数据库的权限:

# 进入MySQL容器,输入环境变量中的PRODUCTION_MYSQL_PASSWORD
docker exec -it database_production mysql -u user -p

在MySQL控制台执行:

GRANT CREATE ON *.* TO 'user'@'%';
FLUSH PRIVILEGES;

退出后重新执行bundle exec rails db:create,如果能成功,说明确实是权限问题。

永久解决方法:

创建MySQL初始化脚本,让容器启动时自动授权:

  1. 在项目根目录创建init.sql文件:
CREATE DATABASE IF NOT EXISTS db_production;
GRANT ALL PRIVILEGES ON db_production.* TO 'user'@'%';
FLUSH PRIVILEGES;
  1. 修改docker-compose.yml中database_production的volumes配置,添加初始化脚本挂载:
database_production:
  # ...其他配置
  volumes:
    - dbdata_production:/var/lib/mysql
    - mysql_socket:/var/run/mysqld
    - ./init.sql:/docker-entrypoint-initdb.d/init.sql # 新增这一行

这样MySQL容器第一次启动时会自动执行脚本,创建数据库并授予完整权限。


2. 修正database.yml的密码配置

你的database.yml中密码是硬编码的"some_password",但Docker环境变量中使用的是APP_DATABASE_PASSWORD=${PRODUCTION_MYSQL_PASSWORD},可能存在密码不匹配的情况(手动连接时你用的是正确的环境变量密码,但db:create用的是硬编码值)。

修改database.yml的production配置:

production:
  <<: *default
  host: database_production
  port: 3306
  database: db_production
  username: user
  password: <%= ENV['APP_DATABASE_PASSWORD'] %> # 改为读取环境变量
  socket: "/var/run/mysqld/mysqld.sock"

3. 替换sleep为健康检查,确保MySQL完全就绪

sleep 5是不可靠的,Ubuntu 20.04和22.04的MySQL启动速度可能不同,导致Rails容器启动时MySQL还没完全准备好接受连接。

修改docker-compose.yml,给MySQL添加健康检查,并让Rails容器等待MySQL就绪:

database_production:
  # ...其他配置
  healthcheck:
    test: ["CMD", "mysqladmin", "ping", "-uuser", "-p${PRODUCTION_MYSQL_PASSWORD}", "-h", "localhost"]
    interval: 5s
    timeout: 5s
    retries: 5

app_production:
  # ...其他配置
  depends_on:
    database_production:
      condition: service_healthy # 替换原来的depends_on配置

4. 检查MySQL Socket权限(针对Ubuntu 20.04差异)

Ubuntu 20.04的Docker环境可能导致共享socket的权限问题,验证方法:

# 查看MySQL容器内socket权限
docker exec -it database_production ls -l /var/run/mysqld/mysqld.sock
# 查看Rails容器内socket权限
docker exec -it app_production ls -l /var/run/mysqld/mysqld.sock

如果Rails容器无法读取socket,可在MySQL容器的command中添加--user=mysql(确保socket属于mysql用户,而Rails容器以root运行,默认有权限读取):

database_production:
  command: mysqld --default-authentication-plugin=mysql_native_password --user=mysql

内容的提问来源于stack exchange,提问作者Simon Mo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 00:27:01