既存のRailsアプリの開発環境をDockerで構築するため、Dockerfile
とdocker-compose.yml
を作成し、db:create
しようとしたら後述のcould not connect to server: Connection refused
というエラーが出ました。
結論としてはこのエラーは、config/database.yml
のhost
をデーターベースのコンテナ名に指定することで解決しました。
環境
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.15.3
BuildVersion: 19D76
$ docker -v
Docker version 19.03.5, build 633a0ea
$ docker-compose -v
docker-compose version 1.25.2, build 698e2846
エラー内容
既存のRailsアプリの開発環境をDockerで構築するため、Dockerfile
とdocker-compose.yml
を作成し、db:create
しようとしたらエラーが出ました。
$ docker-compose run rails bundle exec rails db:create
Starting sample_db_1 ... done
The HashDiff constant used by this gem conflicts with another gem of a similar name. As of version 1.0 the HashDiff constant will be completely removed and replaced by Hashdiff. For more information see https://github.com/liufengyun/hashdiff/issues/45.
could not connect to server: Connection refused
Is the server running on host "localhost" (127.0.0.1) and accepting
TCP/IP connections on port 5432?
could not connect to server: Cannot assign requested address
Is the server running on host "localhost" (::1) and accepting
TCP/IP connections on port 5432?
Couldn't create 'supplebox_development' database. Please check your configuration.
rails aborted!
PG::ConnectionBad: could not connect to server: Connection refused
Is the server running on host "localhost" (127.0.0.1) and accepting
TCP/IP connections on port 5432?
could not connect to server: Cannot assign requested address
Is the server running on host "localhost" (::1) and accepting
TCP/IP connections on port 5432?
/usr/local/bundle/ruby/2.5.0/gems/pg-0.21.0/lib/pg.rb:56:in `initialize'
/usr/local/bundle/ruby/2.5.0/gems/pg-0.21.0/lib/pg.rb:56:in `new'
/usr/local/bundle/ruby/2.5.0/gems/pg-0.21.0/lib/pg.rb:56:in `connect'
/usr/local/bundle/ruby/2.5.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/postgresql_adapter.rb:692:in `connect'
/usr/local/bundle/ruby/2.5.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/postgresql_adapter.rb:223:in `initialize'
/usr/local/bundle/ruby/2.5.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/postgresql_adapter.rb:48:in `new'
/usr/local/bundle/ruby/2.5.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/postgresql_adapter.rb:48:in `postgresql_connection'
/usr/local/bundle/ruby/2.5.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/connection_pool.rb:811:in `new_connection'
/usr/local/bundle/ruby/2.5.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/connection_pool.rb:855:in `checkout_new_connection'
/usr/local/bundle/ruby/2.5.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/connection_pool.rb:834:in `try_to_checkout_new_connection'
/usr/local/bundle/ruby/2.5.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/connection_pool.rb:795:in `acquire_connection'
/usr/local/bundle/ruby/2.5.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/connection_pool.rb:523:in `checkout'
/usr/local/bundle/ruby/2.5.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/connection_pool.rb:382:in `connection'
/usr/local/bundle/ruby/2.5.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/connection_pool.rb:1014:in `retrieve_connection'
/usr/local/bundle/ruby/2.5.0/gems/activerecord-5.2.3/lib/active_record/connection_handling.rb:118:in `retrieve_connection'
/usr/local/bundle/ruby/2.5.0/gems/activerecord-5.2.3/lib/active_record/connection_handling.rb:90:in `connection'
/usr/local/bundle/ruby/2.5.0/gems/activerecord-5.2.3/lib/active_record/tasks/postgresql_database_tasks.rb:12:in `connection'
/usr/local/bundle/ruby/2.5.0/gems/activerecord-5.2.3/lib/active_record/tasks/postgresql_database_tasks.rb:21:in `create'
/usr/local/bundle/ruby/2.5.0/gems/activerecord-5.2.3/lib/active_record/tasks/database_tasks.rb:119:in `create'
/usr/local/bundle/ruby/2.5.0/gems/activerecord-5.2.3/lib/active_record/tasks/database_tasks.rb:139:in `block in create_current'
/usr/local/bundle/ruby/2.5.0/gems/activerecord-5.2.3/lib/active_record/tasks/database_tasks.rb:316:in `block in each_current_configuration'
/usr/local/bundle/ruby/2.5.0/gems/activerecord-5.2.3/lib/active_record/tasks/database_tasks.rb:313:in `each'
/usr/local/bundle/ruby/2.5.0/gems/activerecord-5.2.3/lib/active_record/tasks/database_tasks.rb:313:in `each_current_configuration'
/usr/local/bundle/ruby/2.5.0/gems/activerecord-5.2.3/lib/active_record/tasks/database_tasks.rb:138:in `create_current'
/usr/local/bundle/ruby/2.5.0/gems/activerecord-5.2.3/lib/active_record/railties/databases.rake:29:in `block (2 levels) in <main>'
/usr/local/bundle/ruby/2.5.0/gems/railties-5.2.3/lib/rails/commands/rake/rake_command.rb:23:in `block in perform'
/usr/local/bundle/ruby/2.5.0/gems/railties-5.2.3/lib/rails/commands/rake/rake_command.rb:20:in `perform'
/usr/local/bundle/ruby/2.5.0/gems/railties-5.2.3/lib/rails/command.rb:48:in `invoke'
/usr/local/bundle/ruby/2.5.0/gems/railties-5.2.3/lib/rails/commands.rb:18:in `<main>'
/usr/local/bundle/ruby/2.5.0/gems/bootsnap-1.4.2/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require'
/usr/local/bundle/ruby/2.5.0/gems/bootsnap-1.4.2/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `block in require_with_bootsnap_lfi'
/usr/local/bundle/ruby/2.5.0/gems/bootsnap-1.4.2/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
/usr/local/bundle/ruby/2.5.0/gems/bootsnap-1.4.2/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:21:in `require_with_bootsnap_lfi'
/usr/local/bundle/ruby/2.5.0/gems/bootsnap-1.4.2/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
/usr/local/bundle/ruby/2.5.0/gems/activesupport-5.2.3/lib/active_support/dependencies.rb:291:in `block in require'
/usr/local/bundle/ruby/2.5.0/gems/activesupport-5.2.3/lib/active_support/dependencies.rb:257:in `load_dependency'
/usr/local/bundle/ruby/2.5.0/gems/activesupport-5.2.3/lib/active_support/dependencies.rb:291:in `require'
/myapp/bin/rails:11:in `<top (required)>'
/usr/local/bundle/ruby/2.5.0/gems/spring-2.0.2/lib/spring/client/rails.rb:28:in `load'
/usr/local/bundle/ruby/2.5.0/gems/spring-2.0.2/lib/spring/client/rails.rb:28:in `call'
/usr/local/bundle/ruby/2.5.0/gems/spring-2.0.2/lib/spring/client/command.rb:7:in `call'
/usr/local/bundle/ruby/2.5.0/gems/spring-2.0.2/lib/spring/client.rb:30:in `run'
/usr/local/bundle/ruby/2.5.0/gems/spring-2.0.2/bin/spring:49:in `<top (required)>'
/usr/local/bundle/ruby/2.5.0/gems/spring-2.0.2/lib/spring/binstub.rb:31:in `load'
/usr/local/bundle/ruby/2.5.0/gems/spring-2.0.2/lib/spring/binstub.rb:31:in `<top (required)>'
/myapp/bin/spring:16:in `require'
/myapp/bin/spring:16:in `<top (required)>'
bin/rails:5:in `load'
bin/rails:5:in `<main>'
Tasks: TOP => db:create
(See full trace by running task with --trace)
エラー時のファイル群
Dockerfile
FROM ruby:2.5.3
RUN apt-get update && apt-get install -y build-essential libpq-dev nodejs
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN gem install bundler
RUN bundle install
COPY . /myapp
docker-compose.yml
version: '3'
services:
db:
image: postgres
ports:
- '5432:5432'
volumes:
- pgdata:/var/lib/postgresql/data
rails:
build: .
command: bundle exec rails server -p 3000 -b '0.0.0.0'
depends_on:
- db
ports:
- '3000:3000'
volumes:
- .:/myapp
volumes:
pgdata:
config/database.yml
default: &default
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: postgres
password:
host: localhost
port: 5432
development:
<<: *default
database: supplebox_development
test:
<<: *default
database: supplebox_test
production:
adapter: postgresql
encoding: unicode
pool: 5
database: supplebox_production
username: supplebox
password: <%= ENV['SUPPLEBOX_DATABASE_PASSWORD'] %>
解決
config/database.yml
のhost
にデータベースのコンテナ名であるdb
を指定することで解決しました。
loalhost
のままだと、Railsアプリケーションは、Railsアプリケーション自身のローカルホストのデータベースに接続しようとしますが、そんなデータベースはないよというエラー文が出ていたのでした。
db
を指定することで、データベースはdocker-compose.yml
で指定したdb
コンテナに接続できるのです。
config/database.yml
default: &default
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: postgres
password:
# hostにデータベースのコンテナ名であるdbを指定する
host: db
port: 5432
development:
<<: *default
database: supplebox_development
test:
<<: *default
database: supplebox_test
production:
adapter: postgresql
encoding: unicode
pool: 5
database: supplebox_production
username: supplebox
password: <%= ENV['SUPPLEBOX_DATABASE_PASSWORD'] %>