Docker + Rails6 + PostgreSQL 環境構築

# はじめに
今までRails5 + MySQL での開発しか行ってこなかった自分でしたが、初めてRails6 + PostgreSQL での環境構築を行ったため備忘録も兼ねて記述していきたいと思います。

## 必要なファイル

作業フォルダを作成します。
今回は　`sample_app` とします。

````
$ mkdir sample_app
````
そして必要なファイルを以下の構成で作成します。

````
$ touch ○○(ファイル名）

- sample_app
    - Dockerfile
    - docker-compose.yml
    - Gemfile
    - Gemfile.lock
    - entrypoint.sh
````

ではそれぞれを編集していきます。

### Dockerfile

Rails6 から`Webpacker`がデフォルトで導入されたためインストールする必要があります。
そのため、`Dockerfile`には`Webpacker`をインストールするために必要な`yarn`と`Node.js`をインストールするように記述します。

````Dockerfile
FROM ruby:2.6.5

# 必要なライブラリインストール
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client

# yarnパッケージ管理ツールをインストール
RUN apt-get update && apt-get install -y curl apt-transport-https wget && \
  curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
  echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
  apt-get update && apt-get install -y yarn

# Node.jsをインストール
RUN curl -sL https://deb.nodesource.com/setup_7.x | bash - && \
  apt-get install nodejs

RUN mkdir /sample_app
WORKDIR /sample_app
COPY Gemfile /sample_app/Gemfile
COPY Gemfile.lock /sample_app/Gemfile.lock
RUN bundle install
COPY . /sample_app

COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

CMD ["rails", "server", "-b", "0.0.0.0"]
````

### docker-compose.yml

````docker-compose.yml
version: '3'
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=password
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/sample_app
    ports:
      - "3000:3000"
    depends_on:
      - db
````

### Gemfile

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

### Gemfile.lock

ファイルを作成だけして、編集は何もしません。

### entrypoint.sh

````entrypoint.sh
#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /sample_app/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
````


## Railsアプリの作成
作成した`Dockerfile`元にイメージが`build`し、生成されたコンテナ内で`rails new`を実行します

````
$ docker-compose run web rails new . --force --no-deps --database=postgresql --skip-bundle
````

## bundle install
`rails new`コマンドにより`Gemfile`内の記述が変更されているため`bundle install`をする必要があります。
イメージを`build`することで`bundle install`も実行されるため以下のコマンドを実行します。

````
$ docker-compose build
````

### database.yml
`rails new`で作成された`database.yml`を以下のように編集します。

````config/database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password: password
  pool: 5

development:
  <<: *default
  database: sample_app_development


test:
  <<: *default
  database: sample_app_test
````

## webpackerのインストール

````
$ docker-compose run web bundle exec rails webpacker:install
````

## コンテナを起動

```
$ docker-compose up
````

## DB作成
````
$ docker-compose run web rails db:create
````

# おわり
これで`http://localhost:3000/`にアクセスするとサーバーが立ち上がっていることを確認できるかと思います。
最後まで見ていただき、ありがとうございました。

参考記事
[DockerでRuby on Railsの環境構築を行うためのステップ【Rails 6対応】](https://qiita.com/kodai_0122/items/795438d738386c2c1966)
[Rails6 開発時につまづきそうな webpacker, yarn 関係のエラーと解決方法](https://qiita.com/NaokiIshimura/items/8203f74f8dfd5f6b87a0)
[PostgreSQL（Docker）にRails（Docker）が接続できなくなったから調べてみた。（could not translate host name "db" to address: Name or service not known）](https://qiita.com/at-946/items/2fb75cec5355fad4050d)