Rails test app to reproduce this issue
To setup to reproduce the bug, I have a database.yml
file generated by rails new
, which has a socket setting, but does
not has host
setting. Then when run the rake task, DATABASE_URL is set to mysql2://mysql
.
This test can be run in two easy Docker containers started from a Docker compose file. After clone the app, run
docker-compose build rake
to build the Docker image. Then run
TASKS="db:create" docker-compose run rake
to run the db:create
rake task. The first time you run, you may get output like this due to the mysql container is not started quick enough:
Creating network "railstest_default" with the default driver
Creating railstest_mysql_1
#<Mysql2::Error: Can't connect to MySQL server on 'mysql' (111 "Connection refused")>
Couldn't create database for {"adapter"=>"mysql2", "encoding"=>"utf8", "pool"=>5, "username"=>"root", "password"=>nil, "socket"=>"/tmp/mysql.sock", "database"=>"rails-test_development", "host"=>"mysql"}, {:charset=>"utf8"}
(If you set the charset manually, make sure you have a matching collation)
Created database 'rails-test_development'
#<Mysql2::Error: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2 "No such file or directory")>
Couldn't create database for {"adapter"=>"mysql2", "encoding"=>"utf8", "pool"=>5, "username"=>"root", "password"=>nil, "socket"=>"/tmp/mysql.sock", "database"=>"rails-test_test"}, {:charset=>"utf8"}
(If you set the charset manually, make sure you have a matching collation)
Created database 'rails-test_test'
But notice that the error message for the first run (development
) and the second run (test
) are different: For the development
database, the error message is
#<Mysql2::Error: Can't connect to MySQL server on 'mysql' (111 "Connection refused")>
while for the test
database, the error message is
#<Mysql2::Error: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2 "No such file or directory")>
The first run it attempts to use the host setting in DATABASE_URL
as expected, but the second run it attempts to use the socket connection and bypassed DATABASE_URL
.
If you run the same command again
TASKS="db:create" docker-compose run rake
after the database container is ready, you will get:
Created database 'rails-test_development'
#<Mysql2::Error: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2 "No such file or directory")>
Couldn't create database for {"adapter"=>"mysql2", "encoding"=>"utf8", "pool"=>5, "username"=>"root", "password"=>nil, "socket"=>"/tmp/mysql.sock", "database"=>"rails-test_test"}, {:charset=>"utf8"}
(If you set the charset manually, make sure you have a matching collation)
Created database 'rails-test_test'
The development
database is created successfully, but the test
database was not created although it says otherwise.
You'll get similar result if you run
TASKS="db:drop" docker-compose run rake
or any other database related tasks.