Dockerの環境構築で`could not connect to server: Connection refused`のエラーが出た時の対処法

既存の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`しようとしたらエラーが出ました。

```bash

$ 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)
```

## エラー時のファイル群

```yaml: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
```

```yaml: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:
```

```yml: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`コンテナに接続できるのです。

```yml: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'] %>
```