rails7（apiモード）, react, dockerを使って環境構築してみた

# 環境

* Ruby 3.1.1
* Rails 7.0.2.3(apiモード)
* MySQL8.0
* node 17.2

rails→3001port、react→3000portになるように設定する

# 環境構築

まずは以下のディレクトリとファイルを作成

```
invest_qa
|-api
   |-Gemfile
   |-Gemfile.lock
   |-Dockerfile
   |-entrypoint.sh
|-front
   |-dockerfile
|-docker-compose.yml
```

docker-compose.ymlは以下のように

```yml:docker-compose.yml
version: '3'
services:
  db:
    platform: linux/x86_64 # M1チップ対応のため追記
    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
  api:
    build: ./api
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - ./api:/myapp
      - gem_data:/usr/local/bundle
    ports:
      - "3001:3000"
    depends_on:
      - db
    stdin_open: true
    tty: true
  front:
    build: ./front
    command: yarn start
    ports:
      - "3000:3000"
    volumes:
      - ./front:/myapp
    depends_on:
      - api

volumes:
  mysql-data:
  gem_data:
    driver: local
```

## dockerの環境構築（バックエンド編）

Gemfileは以下のように

```Gemfile:Gemfile
source 'https://rubygems.org'

gem 'rails', '~> 7.0.2.3'
```

Gemfile.lockは何も書かなくてOK

```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 "$@"
```

dockerfileは以下のように

```dockerfile:Dockerfile
FROM ruby:3.1.1
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にbuildしていくのでひとまずフロントエンドの環境構築へ

## dockerの環境構築（フロントエンド編）

Dockerfileは以下のように

```dockerfile:Dockerfile
FROM node:17.2
RUN mkdir /myapp
WORKDIR /myapp
```

## イメージの構築

以下を実行しイメージの構築をする

```
docker-compose build
```

## railsアプリの構築

まずはrailsアプリをapiモードで作成

```
docker-compose run api rails new . --force --no-deps --database=mysql --skip-test --webpacker --api
```

Gemfileが更新されてるのでイメージを再構築する

```
docker-compose build
```

database.ymlを修正する

```yaml:api/config/database.yml
#
# And be sure to use new-style password hashing:
#   https://dev.mysql.com/doc/refman/5.7/en/password-hashing.html
#
default: &default
  adapter: mysql2
  encoding: utf8 #ここ
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password:　password　 #ここ　docker-compose.ymlで設定したパスワード
  host: db　 #ここ　docker-compose.ymlでdepend_onしてる

development:
  <<: *default
  database: myapp_development

# Warning: The database defined as "test" will be erased and
# re-

（以下略）
```

続いてデータベースの作成のため以下を実行

```
docker-compose run api rake db:create
```

## reactアプリの構築

まずはreactアプリの作成

```
docker-compose run front npx create-react-app front
```

frontディレクトリに新しいfrontディレクトリが作成されてしまう。。。
元あるfrontディレクトリにコピペしてなんとかしないといけない
ともあれこれやればなんとかなる。

## それぞれのアプリにアクセス

以下のコマンドを実行してコンテナの構築・起動をする

```
docker-compose up
```

``http://localhost:3001``

![スクリーンショット 2022-03-22 20.01.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645779/bb557f02-53c6-2b8a-efb1-da469b18dd60.png)

``http://localhost:3000``

![スクリーンショット 2022-03-22 20.02.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645779/b6f2060a-493c-f474-b778-2ffb8228fed4.png)

以上で環境構築ができました。