超初心者がDockerでRails6 + Postgresql 環境構築を最後まで

#構築開始にいたるまで
Dockerに触れておきたかったので、上記環境を構築することに。
前知識がまったくないのでトライアンドエラーを繰り返しました...
しかしなんとか構築できたので、メモを残します。
いまいちよくわかってない箇所は注釈や説明に`?`を付けました

#必要なフォルダ、ファイル
任意の名前のフォルダーを用意、ここでは`my_app`とします。

```
$ mkdir my_app
```

`my_app`内に以下のファイルを用意

```
$ touch xxx(必要なファイル名)

- my_app
    - .dockerignore
    - Dockerfile
    - docker-compose.yml
    - Gemfile
    - Gemfile.lock
    - entrypoint.sh
```

それぞれのファイルは以下のような中身に編集していきます。

###.dockerignore
ローカルモジュールとデバッグログがDockerイメージにコピーされるのを防ぎます。
Mac環境とDocker上のLinux環境とでは必要なモジュールが違うから...なのかな？
とにかく、これがないと Node.js 12.xの関係でエラーがでます。

```.dockerignore:.dockerignore
node_modules
npm-debug.log
```


###.Dockerfile
Postgresqlと、rails6のWebpackerに必要なyarnとNode.jsをインストールをします。
羅列されている各コマンドについてはざっくりでしか理解できてません(焦)
勉強の必要がありそうです...

```Dockerfile:Dockerfile
FROM ruby:2.7.1

# 必要なライブラリインストール
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_12.x | bash
RUN apt-get install -y nodejs

# コンテナ内の作業フォルダ構築
RUN mkdir /my_app
WORKDIR /my_app
COPY Gemfile /my_app/Gemfile
COPY Gemfile.lock /my_app/Gemfile.lock
RUN bundle install
COPY . /my_app

#entrypoint.shと接続の設定
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
ここではPostgresqlで使うユーザー名とパスワードを`postgres`とします。
サービスに`web`と`db`がありますね。

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

###Gemfile

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

###Gemfile.lock
ファイル生成のみで、中身を編集する必要はありません。

###entrypoint.sh

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

# 前回のrailsサーバー起動時から残ったserver.pidを消す処理？
rm -f /my_app/tmp/pids/server.pid

# コンテナのメインプロセスを実行(Dockerfile内のCMDで指定したコマンド)
exec "$@"
```

#Railsアプリの作成
`run`でweb単体?が`build`され、webコンテナ内で`rails new`を実行

```
$ docker-compose run web rails new . --force --no-deps --database=postgresql --skip-bundle
```
`--no-deps`:リンクしたサービスを起動しない(webにリンクしたdbを今は起動しない?)
`--skip-bundle`:bundleを実行しない

#bundle install
さきほどの`rails new`で、Gemfileが書き換えられています。
イメージを`build`することによって、`bundle install`も行われるため、以下のコマンドを実行します。

```
$ docker-compose build
```

#データベース設定

作業用フォルダには見慣れたrailsのファイル一式がすでにあると思うので、
`config/database.yml`を以下のように編集します。

```yml:config/database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  #docker-compose.yml内で書いたPostgresqlのユーザー名、パスワードと一致させること
  username: postgres
  password: postgres
  pool: 5

development:
  <<: *default
  database: my_app_development

test:
  <<: *default
  database: my_app_test
```

#webpackerのインストールと設定
###webpackerのインストール
webコンテナ内で`bundle exec rails webpacker:install`を実行。

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

###webpackerの設定
自分の場合、この設定を行わないとサーバー起動時にエラーが起ってしまいます。
`rails webpacker:install`によって生成された`config/webpacker.yml`を以下のように編集します。

```yml:config/webpacker.yml
development:
  dev_server:
    host: webpacker
    hmr: true
```

また`config/environments/development.rb`に以下のコードを加えます。
でもひょっとしたらこの工程だけは必要ないかもしれません。

```ruby:config/environments/development.rb
config.webpacker.check_yarn_integrity = false
```

#コンテナ起動

```
$ docker-compose up
```

この時点で`http://localhost:3000/`にアクセスできますが、
DBがまだ作成されてないので、エラー画面が表示されます。
実に初歩的ですが長い道のりだっただけに、自分はかなり焦りました(笑)

#DB作成

```
$ docker-compose run web rails db:create
```

#構築完了
`http://localhost:3000/`に「Yay! You're on Rails!」があれば成功です！
もし不要なdockerイメージやコンテナが生成されていれば各自で削除してくださいね。

初めての投稿記事につき、至らない点がたくさんあると思います。
そんな記事に最後までお付き合いいただき、ありがとうございました。
記事に間違いがありましたら、ご指摘ください。

#参考

[Docker + Rails6 + PostgreSQL 環境構築](https://qiita.com/Masanori_N/items/86b485ffa036dda5def6)
[docker-compose upの直後Yarnのエラーでコンテナが落ちる問題と解決](https://qiita.com/naokit-dev/items/a5e3101edefd9133c017)
[Node.js Web アプリケーションを Docker 化する](https://nodejs.org/ja/docs/guides/nodejs-docker-webapp/)
[既存のrails6アプリをDocker,webpackerの組み合わせで使いたい](https://teratail.com/questions/227069)
[docker-compose 'up' とか 'build' とか 'start' とかの違いを理解できていなかったのでまとめてみた
](https://qiita.com/tegnike/items/bcdcee0320e11a928d46)