Rails 5.1.5+Docker连接远程MySQL异常:migrate成功但页面调用报错
Hey there, let's break down this weird issue you're facing—since rails db:migrate works, we already know your Docker setup can reach the remote MySQL server and your credentials are valid. The generic 500 error when hitting database-dependent pages points to a runtime problem rather than a core connection issue. Here's how to dig into it step by step:
You mentioned enabling STDOUT logs, but don't just stop at the "something went wrong" message. Run this command to tail your web service logs in real time:
docker-compose logs -f web
Then refresh the problematic page. Scroll up in the logs to find the full error stack trace—this will tell you exactly what's failing (e.g., connection timeouts, rejected connections, missing permissions, or connection pool exhaustion). This is the most critical step—don't skip it.
Sometimes the rails db:migrate command uses different environment variables or a different Rails environment than your running web service. To verify:
- Run a Rails console inside your web container to test a direct database query:
Then try a simple query likedocker-compose exec web rails consoleYourModel.first(replace with one of your actual models). If this throws an error, it will give you specific details about the runtime connection issue. - Double-check that your web service and migrate command are using identical database environment variables (e.g.,
DATABASE_URL,DB_HOST,DB_USER,DB_PASSWORD) in yourdocker-compose.yml.
Remote firewalls often restrict concurrent connections or connection frequency, even if single connections (like those used by db:migrate) are allowed. Rails uses a connection pool (default size: 5) to handle multiple requests at once. To test if this is the issue:
- Temporarily lower the connection pool size in
config/database.yml:production: # ... your existing config pool: 1 - Restart your web service with
docker-compose restart weband test the page again. If it works now, you'll need to coordinate with your server admin to adjust the firewall's concurrent connection limits.
Even if db:migrate succeeded, your MySQL user might be restricted to a specific IP address—and Docker containers can sometimes get new IPs on restart (though Compose usually uses fixed network IPs). On the remote MySQL server, run:
SELECT host, user FROM mysql.user;
Make sure your database user's host value allows the entire Docker network segment (e.g., 172.18.0.% for a default Compose network) instead of a single IP.
If the remote MySQL server requires SSL connections, db:migrate might have automatically negotiated SSL, but your Rails runtime config might not explicitly enable it. Add SSL settings to config/database.yml if needed:
production: # ... your existing config sslmode: require # Uncomment below if your server uses a custom CA certificate # sslca: /path/to/your/ca.pem
Docker's default network timeouts might be shorter than what the remote database requires. Add a connection timeout to your database config to rule this out:
production: # ... your existing config connect_timeout: 10 # in seconds
Start with step 1—getting the exact error message will make all other troubleshooting way faster!
内容的提问来源于stack exchange,提问作者Jose A

