【Mac】「Docker」で「Ruby on Rails 6」「React」と「MySQL 8」で環境構築（CRUDのサンプル付）

# ■ はじめに
SESエンジニアとして、PHPをメインに参画し、現在はJava案件に参画しているTatsuyaです。
そしてこの度転職が決まりまして、9月から新しい職場に！！！！
楽しみもある反面、実は不安要素が。。。

それは、、、
**次の職場は！！Ruby on Rails！！やったことない！！**

> 僕「学習しないと転職した瞬間からお荷物確定ダァー」

と焦り散らかし始めて、先日からRuby on Railsの学習に励み始めたわけなのですが。。。

> 僕「Rubyの公式チュートリアルめちゃくちゃ大変すぎないか！？さらにHerokuとかも使うの！？結構大掛かり！？」

というので、実は挫折しちゃいました。。。
挫折理由としては、チュートリアル自体が骨太ということもありますが、 **Dockerを使った環境構築** も重なって折れちゃいました。~~（最弱）~~

僕は、直接自分のMacにRuby環境は作りたくなかったんで、なんとしてでもDockerでローカル環境を整えたかったのです。~~（次の職場でもDocker使うみたいですしお寿司）~~

ということで、先人の方々が丁寧に書き上げていただいた貴重な文献を元に、実際に動かしながらRubyの動きがわかるような良い感じの環境を作らせていただいて、そこで学習を進めようという方向に舵を切ることになりました。

その過程で、とてもわかりやすく、実際に手を動かしながら理解しやすいと感じた「環境」「サンプルコード」を有り難くミックスさせていただいたので、そちらの結果の方をこの記事でご紹介できればなと思います。

## ◇ 大変お世話になった貴重な参考文献（無許可です。すいません。）
以下に記載した方々のお力をお借りして、良い感じのサンプルサイトの構築ができました。ありがとうございます。
これから環境構築作業に入っていきますが、丁寧に進めたい！という方はぜひ僕の記事と一緒に偉大なる先人方の記事を見ていただければかなり深まるのではないかと思います。

### ◉ 環境
#### [Docker + Ruby on Rails + MySQLで開発環境を新規構築する](https://noknow.info/it/os/build_with_docker_ruby_on_rails_mysql?lang=ja)
- 丁寧な記事で、詳しくソース毎の解説をしてくれています。またDockerのインストールから記載していただいているので、初めてDockerに触るという方にもオススメです。とてもありがたかったです。


### ◉ サンプルコード
#### [Rails + React + AjaxでCRUDのサンプルプロジェクト](https://www.petitmonte.com/ruby/react_crud.html)
#### [Rails + React + AjaxでCRUDのサンプルプロジェクト（ソース一式）](https://github.com/TakeshiOkamoto/mpp_react_crud)
- チュートリアル方式で解説を進めてくださっております。大変わかりやすいです。私はまるっとクローンして動かしたのですが、書きながら学びたい方は順に進めていくのも良いと思います。

### ◉ その他細かい部分でお世話になった記事
#### [Rails on Dockerでcredentialsをeditしたい](https://qiita.com/at-946/items/8630ddd411d1e6a651c6)

## ◇ 感謝と謝罪
- ※基本的に参考記事様の情報をコピペで使用しております。私が今回取り組んだのは、 **環境とサンプルコードのミックス** なので、変にアレンジさせずにほぼ原型のままで使用させていただいております。貴重なお時間を割いて書き上げていただいた記事を丸々コピーするような形になりまして、大変申し訳ないという気持ちと、Rubyの学習コストを下げていただいて誠に有り難うございますという感謝と謝罪を先にさせていただきたいと思います。

---

# ■ 実際に環境を構築していきましょう
## ◇ 前提条件
- Mac
- Docker インストール済みであること
  - まだの方はこちらの[記事](https://noknow.info/it/os/build_with_docker_ruby_on_rails_mysql?lang=ja)から
- git インストール済みであること

## ◇ 最終的なディレクトリ構成
```:ディレクトリ構成
mpp_react_crud
  /mysql
    /Dockerfile
    /my.cnf
  /rails
    /app
    /bin
    /config
    /db
    /log
    /node_modules
    /public
    /tmp
      .browserslistrc
      .gitignore
      .ruby-version
      .babel.config.js
      .config.ru
      Dockerfile
      Gemfile
      Gemfile.lock
      LICENSE
      package.json
      pastcss.config.js
      Rakefile
      README.md
      yarn.lock
  docker-compose.yml
```

## ◇ サンプルプロジェクトをクローン
```bash:terminal
# homeへ
$ cd
# mpp_react_crud ディレクトリを作成
$ mkdir mpp_react_crud
# mpp_react_crud ディレクトリに移動
$ cd mpp_react_crud
# サンプルプロジェクトをclone
$ git clone https://github.com/TakeshiOkamoto/mpp_react_crud.git
# mpp_react_crudプロジェクト の名前を railsに変更
$ mv mpp_react_crud rails
```

## ◇ docker-compose.yml の作成
```bash:terminal
# 『◇ サンプルプロジェクトをクローン』の続きから

# docker-compose.yml を作成する
$ vi docker-compose.yml
# vim画面が開いたら、「iキー」でINSERTモードにし、以下のymlをコピペしてください。
# コピペが完了したタイミングで、「:wq」で保存をして終了してください。
```

```yml:docker-compose.yml
version: "3.7"
services:
  db:
    build: mysql
    image: mpp_react_crud_db
    container_name: mpp_react_crud_db
    ports:
      - 3306:3306
  app:
    build: rails
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    image: mpp_react_crud_app
    container_name: mpp_react_crud_app
    ports:
      - 3000:3000
    volumes:
      - ./rails:/rails
    depends_on:
      - db
```

## ◇ MySQL用のDockerfileとmy.cnfを作成
### ▼ Dockerfile の作成
```bash:terminal
# 『◇ docker-compose.yml の作成』の続きから

# mysql ディレクトリを作成
$ mkdir mysql
# mysql ディレクトリに移動
$ cd mysql
# Dockerfile を作成する
$ vi Dockerfile
# vim画面が開いたら、「iキー」でINSERTモードにし、以下のymlをコピペしてください。
# コピペが完了したタイミングで、「:wq」で保存をして終了してください。
```

```Dockerfile:Dockerfile
FROM mysql:8.0.18

ENV MYSQL_ROOT_PASSWORD root_pass

COPY ./my.cnf /etc/mysql/conf.d/my.cnf
RUN mkdir /var/log/mysql
RUN chown mysql:mysql /var/log/mysql
RUN mkdir /var/run/mysql
RUN chown mysql:mysql /var/run/mysql
```

### ▼ my.cnf の作成
```bash:terminal

# my.cnf を作成する
$ vi my.cnf
# vim画面が開いたら、「iキー」でINSERTモードにし、以下のymlをコピペしてください。
# コピペが完了したタイミングで、「:wq」で保存をして終了してください。
```

```:my.cnf
[mysql]
default-character-set=utf8mb4
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_bin
datadir=/var/lib/mysql
socket=/var/run/mysql/mysql.sock
log-error=/var/log/mysql/mysqld.log
pid-file=/var/run/mysql/mysqld.pid
port=3306
default_authentication_plugin= mysql_native_password
[client]
default-character-set=utf8mb4
```

```bash:terminal
# 最後に mpp_react_crud ディレクトリに戻る
$ cd ..
```

## ◇ Ruby on Rails用のDockerfileとGemfile.lockを作成
### ▼ Dockerfile の作成
```bash:terminal
# 『◇ MySQL用のDockerfileとmy.cnfを作成』の続きから

# rails ディレクトリに移動
$ cd rails
# Dockerfile を作成する
$ vi Dockerfile
# vim画面が開いたら、「iキー」でINSERTモードにし、以下のymlをコピペしてください。
# コピペが完了したタイミングで、「:wq」で保存をして終了してください。
```

```Dockerfile:Dockerfile
FROM ruby:2.6.5

ENV LANG C.UTF-8
ENV APP_HOME /rails

RUN apt-get update -qq && apt-get install -y build-essential nodejs

# もしyarnでエラーが発生した場合
RUN apt-get update -qq && apt-get install -y curl && 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 && apt-get install -y vim

RUN rm -rf /var/lib/apt/lists/*

RUN mkdir $APP_HOME
WORKDIR $APP_HOME
COPY ./Gemfile $APP_HOME/Gemfile
COPY ./Gemfile.lock $APP_HOME/Gemfile.lock
RUN bundle install
COPY . $APP_HOME

EXPOSE  3000
```

### ▼ Gemfile.lock の作成
```bash:terminal
# Gemfile.lock を作成
# 空ファイルで良いので、touch コマンドで作成します。
$ touch Gemfile.lock
```

## ◇ Rails用データベース設定ファイル"database.yml"を編集
```bash:terminal
# 『◇ Ruby on Rails用のDockerfileとGemfile.lockを作成』の続きから

# database.yml を編集
$ vi config/database.yml
# vim画面が開いたら、「iキー」でINSERTモードにし、以下のymlをコピペしてください。
# コピペが完了したタイミングで、「:wq」で保存をして終了してください。
```

```yml:database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password:  root_pass
  host: db

development:
  <<: *default
  database: mpp_react_crud_development

test:
  <<: *default
  database: mpp_react_crud_test

production:
  <<: *default
  database:
  username:
  password:
```

```bash:terminal
# 最後に mpp_react_crud ディレクトリに戻る
$ cd ..
```

## ◇ Dockerイメージをビルド
```bash:terminal
# 『◇ Rails用データベース設定ファイル"database.yml"を編集』の続きから
# Docker イメージをビルド
$ docker-compose build
```

## ◇ docker-composeでアプリを起動〜プロジェクト設定
```bash:terminal
# 『◇ Dockerイメージをビルド』の続きから

# サービスの立ち上げ
$ docker-compose up -d  # -d: バックグラウンドで起動
# bundle インストール
$ docker-compose run app bundle install
# 各種パッケージのインストール
$ docker-compose run app yarn install
# マスターキーの生成
# ファイル生成後、credentials.yml.encの編集画面が表示されるので:q!で終了します。
$ docker-compose run -e EDITOR=vim app rails credentials:edit
# フォルダの生成
$ mkdir rails/app/assets/images
```

## ◇ データベース準備
```bash:terminal
# 『◇ docker-composeでアプリを起動〜プロジェクト設定』の続きから

# データベースの作成
$ docker-compose run app rails db:create
# 各テーブルの作成
$ docker-compose run app rails db:migrate
# 各テーブルの初期データの作成
$ docker-compose run app rails db:seed
```

## ◇ 完成！
最後にコンテナを再起動しましょう。

```bash:terminal
$ docker-compose restart
```

再起動終了後に、http://localhost:3000 にアクセスしてみてください！
すると、以下のようなページが開かれます。

<img width="1677" alt="スクリーンショット 2020-07-26 16.49.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425581/57f61bdd-cd51-ed4f-d0b9-ec4b608ebace.png">


以上でサンプルサイトの環境構築終了です！

# ■ 終わりに
初心者の方だけでなく、経験者の方でもあっても、初めて触る技術の学習にはかなり苦戦すると思います。
そのため、先に「どういうサイトがどのように動いているか」ということを知るだけでも学習効率は上がるんじゃないかなーと思い、今回の作業に取り掛かりました。
まだ私も環境構築をしてすぐにこの記事を書いているので、この環境を使った学習は始めていませんが、実際にログを仕込んでみたりしながら体感的に学ぶ方が飲み込みは早いと考えるので、ガンガンこの環境とこのサイトを元に学習に取り組んでいこうと思います。

この記事は解説部分を完全に端折って、ただただ完成させることだけを目標に書き上げました！
そのため、しっかりと解説を確認したい方は、参考文献様の記事をご確認いただいて、照らし合わせながら進めてほしいと思います。

> 僕「本当に先人の方々はすげえや。」