【Docker】開発環境構築 Rails6 / Ruby2.7 / MySQL8

# はじめに
DockerでRails6, MySQLにて環境構築をする際になかなかてこずってしまったので、備忘録もかねて記事に残します。

つまずいた部分として、
Rails5 とは異なり Rails6 ではモダンなフロントエンド開発を強力にサポートするWebpackをRuby on Railsで使うためのgemパッケージであるWebpackerの導入が必須となったことがある。

※Docker初心者であり各ファイルの記述についても理解できていない部分も多いです。

# 環境・バージョン
- Macbook Air Catalina
- Ruby 2.7
- Rails 6
- MySQL 8.0

# 環境構築完了までの手順
1. プロジェクトのフォルダを用意
2. ５つのファイルを用意
3. 各ファイルを記述
4. Rails プロジェクトの開始（rails new)
5. Dockerイメージのビルド
6. database.yml の編集
7. DBを作成(db:create)
8. コンテナを起動

# 実際に環境構築してみる

### 1. プロジェクトのフォルダを用意
任意の名前のフォルダを作成する（コマンドでなくてもOK）

```
mkdir dockerSampleApp 
```

### 2. ５つのファイルを用意

1.で作成したフォルダ内にファイルを作成する

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

### 3. 各ファイルを記述

#### Dockerfile

プロジェクトのフォルダ名に関係なくmyappの箇所はmyappのままでOKです。

```:Dockerfile
FROM ruby:2.7

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 \
    && apt-get update -qq \
    && apt-get install -y nodejs yarn \
    && mkdir /myapp
    
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp

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: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: password
    ports:
      - '3306:3306'
    command: --default-authentication-plugin=mysql_native_password
    volumes:
      - mysql-data:/var/lib/mysql
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db
    stdin_open: true
    tty: true
volumes:
  mysql-data:
    driver: local
```
#### Gemfile

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

```Gemfile.lock
# このファイルには何も記述しない
```

#### entrypoint.sh

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

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

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
```
### 4. Rails プロジェクトの開始（rails new)

コマンドを実行

```
$ docker-compose run web rails new . --force --no-deps --database=mysql --skip-test --webpacker --api
```
今回使用オプションについて

- ``--force`` 既存のGemfileを上書きする
- ``--no-deps`` リンクしたサービスを起動しない
- ``--database=mysql`` データベースにMySQLを指定
- ``--skip-test`` Minitest のインストールをスキップ（テストはRSpecを導入予定のため）
- ``--webpacker`` webpacker をインストール(Rails6 では必須のパッケージ管理ツール）
- ``--api`` APIだけ作りたいためAPIモードで実行。これにより不要なView・UI関連のライブラリがインストールされない。

※オプションについては適時カスタムして使用する

### 5. Dockerイメージのビルド
イメージビルドとは、各種依存ライブラリやミドルウェアをインストールしたり、自分のアプリケーションをインストール・設定したりすること。

コマンドを実行

```
$ docker-compose build
```
### 6. database.yml の編集

``database.yml``の該当部分を修正。
``docker-compose.yml``の``services``と``MYSQL_ROOT_PASSWORD``の設定に合わせて該当箇所を修正。

```config/database.yml
# ~ 省略 ~

default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password  # -> 空欄を password に修正
  host: db  # -> localhostから db に修正

# ~ 省略 ~
```

### 7. DBを作成(db:create)

コマンドを実行してDBを作成

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

### 8. コンテナを起動

最後にコマンドを実行してコンテナを起動する

```
$ docker-compose up
```
少し時間がかかるかもですが、ターミナルにこんなログが流れればOK

```
web_1  | => Booting Puma
web_1  | => Rails 6.0.3.4 application starting in development 
web_1  | => Run `rails server --help` for more startup options
web_1  | Puma starting in single mode...
web_1  | * Version 4.3.6 (ruby 2.7.2-p137), codename: Mysterious Traveller
web_1  | * Min threads: 5, max threads: 5
web_1  | * Environment: development
web_1  | * Listening on tcp://0.0.0.0:3000
web_1  | Use Ctrl-C to stop
```

``localhost:3000``にアクセスすると無事ページが表示される。はず！！

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621162/c9a272d6-c9e8-52b4-f23d-6f13ae2c2c7b.png" width="500"/>


# 最後に
なんとか環境構築ができました！
今後Dockerなどインフラ面についても学習して理解を深めて行きたいです！

# 参考資料
大変参考にさせていただきました！

- https://qiita.com/nsy_13/items/9fbc929f173984c30b5d
- https://qiita.com/kodai_0122/items/795438d738386c2c1966
- https://qiita.com/azul915/items/5b7063cbc80192343fc0
- https://qiita.com/c5meru/items/1c921676de8a5a038f70


ありがとうございました！！