RubyAPI3、Rails7、React、Mysql8でDockerにて環境構築する方法

## 最初に
SPAアプリケーションを作るために、環境構築をしました。今回の記事は環境構築の備忘録です。

### バージョン
- Ruby:3.2.1
- Ruby on Rails:7.0.4
- MySQL:8.0.32
- React:v18
- docker-compose:v3.8

## アプリケーションの基盤を作成
RailsとReact用のディレクトリを作成します。Railsにはbackendディレクトリ、Reactにはfrontendディレクトリを作成します。
```
mkdir practiceApp
cd practiceApp
mkdir backend
mkdir frontend
touch docker-compose.yml
touch backend/Gemfile
touch backend/Gemfile.lock
touch backend/entrypoint.sh
touch backend/Dockerfile
touch frontend/Dockerfile
```

## Rails用の設定を作成
以下のファイルにRailsの設定を追記します。
- 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 "$@"
```
- Dockerfile
```
FROM ruby:3.2.1
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs

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

# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]
```
- Gemfile
```
source "https://rubygems.org"
ruby "3.2.1"

# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main"
gem "rails", "~> 7.0.4"
```
- docker-compose.yml
```
version: '3.8'

services:
  db:
    image: mysql:8.0
    platform: linux/x86_64
    command: --default-authentication-plugin=mysql_native_password
    ports:
      - "4306:3306"
    volumes:
      - db:/var/lib/mysql
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
    security_opt:
      - seccomp:unconfined
  backend:
    build:
      context: ./backend/
      dockerfile: Dockerfile
    stdin_open: true
    tty: true
    volumes:
      - ./backend:/myapp
      - bundle:/usr/local/bundle
    command: bash -c "rm -rf tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    depends_on:
      - db
    ports:
      - "3001:3000"
    environment:
      TZ: Asia/Tokyo
volumes:
  db:
    driver: local
  bundle:
    driver: local
```
上記のファイルを作成したら、以下のコマンドを実行して下さい。
```
docker-compose run --no-deps backend rails new . --force -d mysql --api --skip-test
```
dbという名前でデータベース環境を作成している為、以下のファイルの`default`に`host: db`を追加
- database.yml
```
default: &default
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: root
password:
host: db // この箇所を修正
```

## React用の設定を作成
- practiceApp/frontend/Dockerfile
```
  FROM node:14.17.1-alpine
  WORKDIR /usr/src/app
```
- docker-compose.yml
元々ある`docker-compose.yml`の`services:`に`frontend:`を追加
```
  version: '3.8'

  services:
    db:
      image: mysql:8.0
      platform: linux/x86_64
      command: --default-authentication-plugin=mysql_native_password
      ports:
        - "4306:3306"
      volumes:
        - db:/var/lib/mysql
      environment:
        MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
      security_opt:
        - seccomp:unconfined
    backend:
      build:
        context: ./backend/
        dockerfile: Dockerfile
      stdin_open: true
      tty: true
      volumes:
        - ./backend:/myapp
        - bundle:/usr/local/bundle
      command: bash -c "rm -rf tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
      depends_on:
        - db
      ports:
        - "3001:3000"
      environment:
        TZ: Asia/Tokyo
    frontend: // このfrontendを追加
      build:
        context: ./frontend/
        dockerfile: Dockerfile
      volumes:
        - ./frontend:/usr/src/app
      command: sh -c "cd app && npm start"
      ports:
        - "3000:3000"
  volumes:
    db:
      driver: local
    bundle:
      driver: local
```
以下のコマンドでDockerのイメージを実行して、Reactのテンプレートを作成
```
docker-compose run --rm frontend sh -c "npx create-react-app app"
```

## 動作確認
以下のコマンドで今回作成したDockerを起動させましょう。
```
docker-compose up
```
Dockerを起動させた後、まだRailsのデータベースが作成されていないので、以下のコマンドでデータベースを作成して下さい。
```
docker-compose exec backend rails db:create
```
ブラウザで`http://localhost:3000/`及び`http://localhost:3001/`にアクセスしてみて下さい。
それぞれReactの画面とRailsの画面が表示されたら、環境構築の出来上がりです。

## Git管理
このままでは、RailasとReactでGit管理されてしまう為、以下のコマンドを実行して下さい。
```
rm -rf backend/.git
rm -rf frontend/.git
git init
```

## 最後に
環境構築って結構骨が折れますよねw 今回は他の方の記事を参考に現時点でのRailsやReactなどでの最新の環境を作るようにしてみました。
自分は環境構築あまり好きじゃないですが、とにかく苦手意識を持たずにならしていこうかと思います。
この後は環境構築せっかくしたので、色々触ってみようと思います。
ここまで読んで下さりありがとうございました〜
## 参考資料
- [Rails6.1 + MySQL + ReactでのDocker環境を構築する](https://qiita.com/ryouzi/items/c8c3fa4a5e16e6710d6c)
- [DockerHub公式 Ruby](https://hub.docker.com/_/ruby)
- [Ruby on Rails公式サイト](https://rubyonrails.org/)
- [アプリケーションのセットアップをしよう](https://zenn.dev/farstep/books/7f169cdc597ada/viewer/5ff63c)