RailsでDocker環境構築

今回はDockerで既存のRails環境を構築し直したときの手順を記載したいと思います。

DBはMySQLを使っています。
比較として確認したい場合は下記投稿を参考にしてください。(database.ymlに変更を入れているので)
[RailsにMySQLを導入する](https://qiita.com/kumas/items/e4c18472daadb6b2fe0f)

##Dockerfileの作成
まずは`Dockerfile`を作成します。プロジェクトのRootディレクトリに作成しました。
`Dockerfile`とは[docker hub](https://hub.docker.com/)で公開されているDockerイメージをそのまま使うのではなく、必要なパッケージやアプリ、各種設定を含んだDockerイメージを自分でカスタマイズしたファイルです。

```ruby:DockerFile
FROM ruby:2.7.0

# パッケージリストの更新(エラー以外は表示させない)
RUN apt-get update -qq && apt-get install -y nodejs yarnpkg
RUN ln -s /usr/bin/yarnpkg /usr/bin/yarn

# 作業ディレクトリの作成、設定
RUN mkdir /app
WORKDIR /app

#ローカルのGemfileを追加する
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock

RUN bundle install
COPY . /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"]
```

`FROM`はベースとするDockerイメージを指定しています。自分の環境にはrubyのバージョン2.7.0が入っているので、指定しました。

`RUN`はコマンドを実行してイメージレイヤを作成します。パッケージをコンテナにインストールするために使用されます。

`ENTRYPOINT`は実行するファイルを指定しています。
entrypoint.shを作成して、コンテナ起動時に実行するようにします。

##entrypoint.shの作成
`Dockerfile`で指定した`entrypoint.sh`の作成を行います。

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

# すでに起動しているserver.pidを削除する
rm -f /app/tmp/pids/server.pid

# コンテナのメインプロセスを実行する
exec "$@"
```

`pid`は、開発用WEBサーバを起動するときに tmp/pids/server.pidに書き込まれ、終了するときに削除されます。
`server.pid`に`pid`が書かれていると開発用WEBサーバが起動中と判断されてしまうので、削除するという手順を入れています。

##dockr-compose.ymlの作成

```yml:dockr-compose.yml
version: '3'
services:
  db:
    image: mysql:8.0
    ports:
      - 127.0.0.1:3333:3306
    volumes:
      - ./tmp/db:/var/lib/mysql
    environment:
       MYSQL_ROOT_PASSWORD: <%= ENV['DATABASE_DOCKER_PASSWORD'] %>
       MYSQL_ROOT_HOST: <%= ENV['DATABASE_DEV_HOST'] %>
    env_file:
      - ./.env

  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/app
    ports:
      - "3000:3000"
    depends_on:
      - db
    env_file:
      - ./.env
```

##database.ymlの修正
DBコンテナでMySQLクライアントを使うので、すでにMySQLをインストールしてDB作成している場合は記載の修正が必要な箇所があります。

```yml:database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: <%= ENV['DATABASE_DOCKER_USER'] %>
  password: <%= ENV['DATABASE_DOCKER_PASSWORD'] %>
  host: <%= ENV['DATABASE_DOCKER_HOST'] %>
  socket: /tmp/mysql.sock
```

今回はusername、password、hostはDockerのDBコンテナの中のMySQLのデータに変更しています。
`.env`ファイルに記載しています。

##コンテナ起動
上記までの手順で設定は完了したので、Dockerコンテナを起動しましょう。

```shell:Dockerイメージ作成
$ docker-compose build
```

上記コマンドで`docker-compose.yml`の内容に基づいてイメージを作成します。

イメージ作成後は、`docker-compose up -d`でコンテナを起動します。

```shell:Dockerコンテナ起動
$ docker-compose up -d
```

ここで、エラーが2箇所で出たので軽く説明します。

**①warning Integrity check: System parameters don't match**

下記のようなエラーが発生しました。

```
warning Integrity check: System parameters don't match                                                                                                                                                 
error Integrity check failed                                                                                                                                                                           
error Found 1 errors.                                                                                                                                                                                  


========================================
  Your Yarn packages are out of date!
  Please run `yarn install --check-files` to update.
========================================


To disable this check, please change `check_yarn_integrity`
to `false` in your webpacker config file (config/webpacker.yml).


yarn check v1.13.1
info Visit https://yarnpkg.com/en/docs/cli/check for documentation about this command.
```

yarnで古いパッケージを使っていると発生するらしいですが、`yarn upgrade`しても解消されなかったので、コンソールに表示されている方法で解決しました。(webpackerを導入している場合は発生する可能性があります。)

```ruby:config/webpacker.yml
# Verifies that correct packages and versions are installed by inspecting package.json, yarn.lock, and node_modules
check_yarn_integrity: false
```

**②Authentication plugin 'caching_sha2_password' cannot be loaded**

これはDockerのDBコンテナの中の認証プラグインが違うので、DBコンテナに入って修正をしてください。

修正の仕方は下記投稿に記載しています。
[RailsにMySQLを導入する](https://qiita.com/kumas/items/e4c18472daadb6b2fe0f)

```shell:DBコンテナに入る
$ docker-compose exec db bash
```

上記でDBコンテナに接続し、rootでログインできると思います。

簡単になりましたが、調べてわかったことは追記していこうと思います！

####参照
[docker-compose で Rails6 + MySQL な環境を構築する](https://blog.toshimaru.net/rails-on-docker-compose/)
[yarnが原因でdocker-compose runが実行できないときの対処法](https://qiita.com/KenAra/items/2708ce3d5c80c4f24920)
[Docker × Ruby on Rails × MySQLの環境構築](https://qiita.com/tatsuo-iriyama/items/0bf3b08de03280314c91)