既存のRailsアプリのローカル環境にDockerを導入する方法【Rails6 / MySQL8】

# はじめに

本記事は私が既存のポートフォリオアプリのローカル環境に`Docker`を導入した際の手順になります。
`Docker`の公式ドキュメントは`PostgreSQL`での手順解説になっているため`MySQL`になると公式ドキュメントの手順解説はなく、
また、`Rails6`での情報も`Rails5`と比べるとやはり少なく、結果、`Rails6`＋`MySQL`という組み合わせでの情報がとても少なかったです。
そのため、私自身様々なエラーが出て試行錯誤しましたので、本記事がこれから`Rails6`＋`MySQL`という組み合わせで`Docker`を導入する方の助けになれば幸いです。
なお、筆者は就職活動中の実務未経験の初学者のため、誤っている点などあるかもしれません。
その際はコメントにて教えて頂けると幸いです。

# 前提条件
+ `Mac版 DockerDesktop`のインストールが完了していること
+ `Docker`が起動済みであること 
   
※筆者の場合、上記インストールと起動は[「ゼロからはじめるDockerによるアプリケーション実行環境構築」](https://www.udemy.com/course/docker-k)を観ながらやりました。
`Docker`の全体像を学ぶ上でもとてもわかりやすく、おすすめです。

# バージョン
+ Ruby 2.6.5  
+ Rails 6.0.3.2
+ MySQL 8.0.21


# 手順１ Dockerfile作成
既存アプリケーションのルートディレクトリに`Dockerfile`を作成し、下記のように記述します。  
**※今回はアプリのディレクトリ名をsample_appとします。
ここはあなたのアプリのディレクトリ名に置き換えてください。**

```dockerfile:Dockerfile
FROM ruby:2.6.5
RUN 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
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs yarn
WORKDIR /sample_app
COPY Gemfile ./Gemfile
COPY Gemfile.lock ./Gemfile.lock
RUN gem install bundler
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`を作成し、下記のように記述します。

```docker-compose.yml
version: '3' #docker-composeのバージョン
services:
  db:
    image: mysql:8.0.21 #既存アプリとあわせる。ターミナルに[$ mysql --version]で確認
    environment:
      MYSQL_ROOT_PASSWORD: vxgbizakqc #あなたのパスワード
      MYSQL_DATABASE: root
    ports:
      - "4306:3306"
    volumes:
      - ./mysql-confd:/etc/mysql/conf.d
  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
    tty: true
    stdin_open: true
volumes:
  mysql-data:

```

# 手順３　entrypoint.sh作成

こちらも手順１・手順２と同じく、既存アプリケーションのルートディレクトリに`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 "$@"

```

# 手順４　config/database.ymlの編集
`config`ディレクトリにある`database.yml`を下記のように編集します。

```config/database.yml

default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: vxgbizakqc #あなたのパスワード
  socket: /tmp/mysql.sock
  host: db

development:
  <<: *default
  database: sample_app_development

test:
  <<: *default
  database: sample_app_test

```

# 手順５　Dockerイメージの作成

ターミナルで下記のコマンドを実行し、`Dockerイメージ`を作成します。

```terminal:ターミナル
MacBook-Pro:sample_app$ docker-compose build
```

# 手順6　Dockerコンテナを起動
ターミナルで下記のコマンドを実行し、`Dockerコンテナ`を起動します。

```terminal:ターミナル
MacBook-Pro:sample_app$ docker-compose up -d
```

# 手順７　コンテナ内にデータベースを作成する
ターミナルで下記のコマンドを実行し、コンテナ内にデータベースを作成します。

```terminal:ターミナル
MacBook-Pro:sample_app$ docker-compose run web rails db:create
```
上のコマンドを実行すると先ほど編集した`database.yml`を元にデータベースを作成します。
データベースの作成が成功すると下記のように表示されます。

```terminal:ターミナル
reating sample_app_web_run ... done
Created database 'sample_app_development'
Created database 'sample_app_test'
```

# 手順８　作成したデータベースのマイグレーションを実行
ターミナルで下記のコマンドを実行し、データベースのマイグレーションを実行します。

```terminal:ターミナル
MacBook-Pro:sample_app$ docker-compose run web rails db:migrate
```
データベースのマイグレーションが成功すると下記のように表示されます。

```terminal:ターミナル
Creating sample_app_web_run ... done
== 20209165960112 DeviseCreateUsers: migrating ================================
-- create_table(:users)
   -> 0.0253s

　　#中略

-- add_index(:notifications, :comment_id)
   -> 0.0251s
== 20209165960112 CreateNotifications: migrated (0.1280s) =====================
```

# 手順９　Gemのインストール
さぁ、長かったDocker導入もこれでいよいよラストです。
ターミナルで下記のコマンドを実行し、`Gem`をインストールします。

```terminal:ターミナル
MacBook-Pro:sample_app$ docker-compose exec web bundle install
```

以上です！！
`localhost:3000`に接続するとアプリケーションが表示されています。


# 参考文献
今回は以下の記事や動画教材を参考にさせて頂いた結果Dockerを導入することができました。
記事を書いて下さった方々、動画教材作成者の小島様、ありがとうございます。

+ [既存のRails6アプリをDocker化しつつCircleCIでシステムスペックも実行できる環境を作る](https://qiita.com/kenz-dev/items/e3d970b59bf106cab19e)
+ [DockerでRuby on Railsの環境構築を行うためのステップ【Rails 6対応】](https://qiita.com/kodai_0122/items/795438d738386c2c1966)
+ [既存のRailsアプリにDockerを導入する手順](https://qiita.com/kenz-dev/items/b9e716204e0cd0cea447)
+ [【Docker環境構築/Rails6~,MySQL】ローカル環境で作成中の既存アプリをDocker環境に移行する手順](https://qiita.com/covalt_ta/items/624364f1d72804044475)
+ [「ゼロからはじめるDockerによるアプリケーション実行環境構築」](https://www.udemy.com/course/docker-k)