【Rails6】既存アプリをDockerに配置する流れ

## 環境
・Docker 20.10.22
・Rails6.1
・Mysql５.7

## はじめに
Railsチュートリアルを完走したので、練習のためにアプリをDockerに配置してみようと思いました。
## ファイルの作成
必要になるファイルは、以下の5つ
+ Dockerfile
+ docker-compose.yml
+ Gemfile
+ Gemfile.lock
+ entrypoint.sh
`Dockerfile` `docker-compose.yml` `docker-entrypoint.sh`ファイルを作成する。
```:appディレクトリ
$ touch {Dockerfile,docker-compose.yml,Gemfile,Gemfile.lock,entrypoint.sh}
```

## Dockerfile
Dockerfile(イメージを作成する時に使用するファイル)
```Docker:Dockerfile
FROM ruby:3.1.1
RUN apt-get update -qq \
&& apt-get install -y nodejs npm \
&& npm install --global yarn \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

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

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

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

```

### CMD
基本的な使い方
```Docker
CMD [“実行ファイル”, “パラメータ1”, “パラメタ2”…]
```
```Docker
CMD ["rails", "server", "-b", "0.0.0.0"]
```
+ `exec`は処理を実行するコマンドであり、`"$@"`は全ての引数という意味。
つまり`exec rails server -b 0.0.0.0`という処理が実行される。

+ `exec rails server -b 0.0.0.0`は`rails server`をコンテナ内のすべてのIPに紐づけている。

`-b`　railsのプロセスをどのIPアドレスにバインドするか。
`0.0.0.0`を指定することで、コンテナ内のサーバーにアクセスできるようになる。
[参考](https://qiita.com/Masato338/items/f162394fbc37fc490dfb)

### EXPOSE
コンテナが接続用にリッスンするポートを指定する。
基本的にはローカル環境なら3000を指定

## docker-entrypoint.sh
初回起動時のみに処理したい内容を記述するヘルパースクリプト。
`ENTRYPOINT`で読み込ませることができる。

[公式ドキュメントより](https://docs.docker.jp/engine/userguide/eng-image/dockerfile_best-practice.html)
>ENTRYPOINT のベストな使い方は、イメージにおけるメインコマンドの設定です。これによりイメージを指定したコマンドを通して実行します（そして、 CMD がデフォルトのフラグとして使われます）。
```bash:entrypoint.sh
#!/bin/bash

#エラー発生時、スクリプトを修了する
set -e

# 初期に作成されるPIDを削除する
# 削除しないと次回起動時にエラーが出る
rm -f /rails-vue/tmp/pids/server.pid

# DockerfileのCMDにセットしたすべての引数を実行する
exec "$@"
```

## docker-compose.yml
```yml:docker-compose.yml
version: "3"
services:
  web:
    container_name:  sample_app_local
    build: .
    # -cで、渡されたコマンドを実行
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    # データの永続化（ホスト側のカレントディレクトリにマウントする）
    volumes:
      - .:/myapp
    # ポートの指定（外部からのアクセス時のポート：Dockerコンテナからアクセス時のポート）
    ports:
      - "3000:3000"
    depends_on:
      - db
  
  db:
    image: mysql:5.7
    #データが消えないように、ボリュームを作成。
    volumes:
      - mysql-data:/var/lib/mysql 
    environment:
      MYSQL_ROOT_PASSWORD: docker
    ports:
      - 3306:3306

volumes:
  mysql-data:
```
`db:`の`environment`の`MYSQL_ROOT_PASSWORD:`は必須です。
`config/database.yml`のpasswordと一致させます。

### volumesの動き
個人的にvolumeの動きが曖昧だったので整理します。

mysql-dataという名前でコンテナ内のvolumesに新規作成。DBのデータはここに保存されていく
```yml
volumes:
  mysql-data:  
```
上記のボリュームに保存されたデータを、コンテナ内アプリの`/var/lib/mysql`にコピー
```yml
db:
  volumes:
    - mysql-data:/var/lib/mysql  
```

## config/database.yml
主に、passwordの設定やhostの設定を行います。
```yml:config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  charset: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  password: docker  #docker-compose.ymlのMYSQL_ROOT_PASSWORDと一致させる
  socket: /tmp/mysql.sock
  host: db    #追記
```

## サービス構築、立ち上げ
### ビルド
```
$ docker-compose build
```
### 立ち上げ
```
$ docker-compose up -d

-d デタッチモード
```
### yarn install
私の環境ではwebサーバーを立ち上げる際に下記のようなエラーが出ました。
```
========================================
  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.22.19
info Visit https://yarnpkg.com/en/docs/cli/check for documentation about this command.
```
そのためwebサーバーでyarn installを実行します
```
$ docker-compose run web yarn install 
```
### DB作成、マイグレート
```
$ docker-compose run web rails db:create

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

## 参考サイト
[DockerでRails環境を構築してみた](https://rightcode.co.jp/blog/information-technology/docker-rails-environment-setup-syain)
[DockerでRuby on Railsの環境構築を行うためのステップ【Rails 6対応】](https://qiita.com/kodai_0122/items/795438d738386c2c1966)
[rails s -b 0.0.0.0 のオプション-bの意味](https://qiita.com/Masato338/items/f162394fbc37fc490dfb)
[[Rails][docker]Please run `yarn install --check-files`を解決する](https://qiita.com/ryoji2405/items/1de1f2e9e206382c4aa5)