【Docker】Rails + PostgreSQLの開発環境構築時に「psql: could not connect to server: No such file or directory」

## はじめに

ここ数年Docker関連の記事をよく見かけるようになりました。Qiitaのタグランキングを見ても常にトップ10入りを果たしており、まさにトレンド、今時の技術といった感じがします。

そんなこともあり、今回は試しにDockerを用いて、Rails + PostgreSQLの開発環境構築を行ってみました。その途中でタイトルのエラーに出会い、一応の解決策が得られたため、記事にしました。

## 作成したファイルの中身

主に下記の記事を参考にDockerfileおよびdocker-compose.yamlを作成しました。
[Rails+PostgreSQLの環境をdocker-composeで作成する](https://qiita.com/atizawa/items/4ca6306087e3813b0941)
[Docker初心者がRails + PostgreSQL or MySQLで仮想環境構築した手順を丁寧にまとめる](https://qiita.com/hogehoge1234/items/28be70b674e24427491e)

作成したファイルは以下のとおりです。

``` Docker:Dockerfile

FROM ruby:2.6.3-stretch

RUN apt-get update &&\
    apt-get install -y nodejs build-essential libpq-dev postgresql-client

RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp
```

``` Docker:docker-compose.yaml
version: "3"
services:
  db:
    image: postgres:11.4-alpine
    ports:
      - "5432:5432"
    environment:
      - "POSTGRES_USER=postgres"
      - "POSTGRES_PASSWORD=password"
    volumes:
      - "./postgres-data:/var/lib/postgresql/data"
  web:
    build:
      context: .
      dockerfile: Dockerfile
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - ".:/myapp"
    ports:
      - "3000:3000"
    tty: true
    depends_on:
      - db
    working_dir: "/myapp"
    environment:
      - "DATABASE_HOST=db"
      - "DATABASE_PORT=5432"
      - "DATABASE_USER=postgres"
      - "DATABASE_PASSWORD=password"
```

``` ruby:Gemfile
source 'https://rubygems.org'
gem 'rails', '~> 5.2.3'
```

## コンテナの作成と起動
ファイルを作成したら、コンテナの作成と起動です。

`$ docker-compose up --build`

でコンテナを作成/起動し、

`$ docker exec -it コンテナ名(web) /bin/bash`

でコンテナに入り、rails new および　bundle installを行います。

そして最後に
`rails db:create`
でdbを作成し、localhostに接続すると無事にアプリケーションが起動し、いつもの画像がお迎えしてくれました。

<img width="598" alt="スクリーンショット 2019-08-08 20.33.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239294/5690694a-94c6-cc3e-4593-2c5a97583e6e.png">

## エラーとの遭遇
というわけで、ここまでは良かったのですが、コンテナ内において、DBが実際に作成されているかクライアントツールを使って確認しようとしたところ下記のようなエラーが発生しました。

```
# psql -l
psql: could not connect to server: No such file or directory
	Is the server running locally and accepting
	connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
```

検索をしてみるとstack overflowにて下記の回答を発見することができました。
[Installing PostgreSQL within a docker container](https://stackoverflow.com/a/41484929)

読んでみると1行目にズバリ原因が書いてありました。

> The problem is that the your application/project is trying to access the postgres socket file in the HOST machine (not docker container).

どうやらdockerコンテナではないソケットファイルに接続しようとしてエラーが発生していた模様です。

そこで、同サイトの[この回答](https://stackoverflow.com/a/52442893)を参考にPostgreSQLのコマンドを調べてみると下記のサイトを発見。
[PostgreSQLへの接続と切断](https://www.dbonline.jp/postgresql/connect/index2.html#section1)

サイトとdocker-compose.yamlを参考に下記のようにコマンドを叩くと

```
# psql -h db -U postgres
```

```
Password for user postgres: 
```
とパスワードが求められるので、docker-compose.yamlに記載した値を入力。
すると、

```
psql (9.6.13, server 11.4)
WARNING: psql major version 9.6, server major version 11.
         Some psql features might not work.
Type "help" for help.

postgres=#
```
と無事にデータベースに接続ができ、

```
postgres-# \l
```
と打つと

```
                                     List of databases
       Name        |  Owner   | Encoding |  Collate   |   Ctype    |   Access privileges   
-------------------+----------+----------+------------+------------+-----------------------
 myapp_development | postgres | UTF8     | en_US.utf8 | en_US.utf8 | 
 myapp_test        | postgres | UTF8     | en_US.utf8 | en_US.utf8 | 
 postgres          | postgres | UTF8     | en_US.utf8 | en_US.utf8 | 
 template0         | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
                   |          |          |            |            | postgres=CTc/postgres
 template1         | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
                   |          |          |            |            | postgres=CTc/postgres
(5 rows)
```

↑のように一覧が表示され、無事に`myapp_development`と`myapp_test`が作成されていることを確認することができました。

## まとめ
というわけで、dockerにおいてPostgreSQLを用いて開発環境構築をしている際に

```
psql: could not connect to server: No such file or directory
	Is the server running locally and accepting
	connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
```
こんなエラーに出会ったら[このサイト](https://www.dbonline.jp/postgresql/connect/index2.html#section1)などを参考にホスト名やロール名を指定して接続してみてください。

微力ではありますが、この記事が誰かのお役に立てば幸いです。
理解の誤りやもっと良い方法がありましたら、ご教示ください。
最後までお読みいただきありがとうございました。

## 参考にしたサイト
- dockerを用いた開発環境構築
 - https://qiita.com/atizawa/items/4ca6306087e3813b0941
 - https://qiita.com/hogehoge1234/items/28be70b674e24427491e
- 原因調査と解決
 - https://stackoverflow.com/a/41484929
 - https://www.dbonline.jp/postgresql/connect/index2.html#section1