【Rails7 × Next.js】Dockerで環境構築してみる。

# 概要
Rails7がリリースされたから環境構築の手順があれば後から楽だなと思ったから、Next.jsをフロントにする前提で構築してみました。


# 環境
Ruby： 3.1.1
Rails： 7.0.2.3
Postgres： 14.2
Docker： 20.10.13
docker-compose： 2.3.3

# 手順
## 1.プロジェクト立ち上げ前にファイルを作成する
以下の構造でファイルを作成する。

```ruby
.
├── frontend
　　     ├── Dockerfile
├── backend
　　     ├── Dockerfile
　　     ├── Gemfile
　　     ├── Gemfile.lock # 空でOK
├── docker-compose.yml
```


## 2.docker-compose.ymlを記述する

```docker-compose.yml
version: '3.7'

services:
  postgres:
    image: postgres:11.6-alpine
    ports:
      - '5432:5432'
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_INITDB_ARGS: '--encoding=UTF-8 --locale=ja_JP.UTF-8'
      TZ: Asia/Tokyo
    volumes:
      - postgres_volume:/var/lib/postgresql
    hostname: postgres
  backend:
    tty: true
    depends_on:
      - postgres
    build:
      context: ./backend/
      dockerfile: Dockerfile
    ports:
      - 3000:3000
    volumes:
      - ./backend:/app
    command: rails server -b 0.0.0.0
  frontend:
    build:
      context: ./frontend/
      dockerfile: Dockerfile
    volumes:
      - ./frontend/app:/usr/src/app
    command: 'yarn dev'
    ports:
      - "8000:3000"
volumes:
  postgres_volume:
    driver: local
```


## 3.frontend/Dockerfileの中身を記述する

```frontend/Dockerfile
FROM node:14-alpine
WORKDIR /usr/src/app
```


## 4.backend/Dockerfileの中身を記述する

```backend/Dockerfile
FROM ruby:3.1.1
RUN apt-get update -qq \
 && apt-get install -y nodejs postgresql-client npm \
 && rm -rf /var/lib/apt/lists/* \
 && npm install --global yarn
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN bundle install

# 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

# Configure the main process to run when running the image
CMD ["rails", "server", "-b", "0.0.0.0"]

```

## 5.Gemfileの中身を記述する

```Gemfile
source 'https://rubygems.org'
gem "rails", "~> 7.0.2", ">= 7.0.2.3"
```

## 6.Next.jsアプリケーションを作成する

まずは`frontned`ディレクトリに移動する

```bash
$ cd frontend
```

`frontned`ディレクトリ内にyarn createでアプリを作成します。

```bash
$ docker-compose run --rm frontend yarn create next-app .
```

`docker-compose up`でコンテナを起動し、
[localhost:8000](localhost:8000)にアクセスして以下の画面が表示されていればOK!!

![スクリーンショット 2022-03-28 21.34.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622448/3db89674-a890-c3c1-1ce9-85e157f73637.png)


## 7.Railsアプリケーションを作成する

まずは`backend`ディレクトリに移動する

```bash
$ cd backend
```

そして`rails new`をする。

```bash
$ docker-compose run --rm --no-deps backend bundle exec rails new . --api --force --database=postgresql --css=bootstrap
```

オプションの詳細は以下の通りです。
| オプション | 内容 |
|:-:|:-:|
| --rm  | 実行後にコンテナを削除  |
| --no-deps  | リンクしたサービスを起動  |
| --api  | APIモードで作成  |
| --force  | ファイルが存在する場合に上書き  |
| --database  | データベースの種類を指定  |
| --css  | CSSプロセッサを選択  |

次に`config/database.yml`を修正する。

```config/database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: postgres
  password: postgres
  host: postgres

development:
  <<: *default
  database: postgres_development

test:
  <<: *default
  database: postgres_test

production:
  <<: *default
  database: postgres_production
  password: <%= ENV["POSTGRES_DATABASE_PASSWORD"] %>
```

最後にデータベースを作成しましょう。

```bash
$ docker-compose run --rm backend rails db:create
```

`docker-compose up`でコンテナを起動し、
[localhost:3000](localhost:3000)にアクセスして以下の画面が表示されていればOK!!

![スクリーンショット 2022-03-28 21.24.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622448/a21b3706-487d-9e77-1408-03bfaf49bd55.png)

# トラブルシューティング
## Rubyのバージョンエラーが発生した場合

`rbenv: version `3.1.1' is not installed (set by /Users/~~/.ruby-version)`のようなエラーが発生した場合は以下のコマンドを順に実行する。

```bash
$ brew upgrade ruby-build

$ ruby-build --version

$ rbenv install --list

$ rbenv install 3.1.1

$ rbenv local 3.1.0
#=> 現在のアプリケーションだけでなく、全体の適用バージョンを変更したい場合はglobalを指定する

$ ruby -v
#=> ruby 3.1.1p18 のような表示ならOK
```

## 「Gemfileが見つからない」というエラーが発生した場合

`Could not locate Gemfile or .bundle/ directory`のようなエラーが発生した場合は以下のコマンドを実行する。

```bash
$ cd Gemfileがあるディレクトリ
#=> 現在の位置がGemfileが配置された位置にいないため
```

## その後のGitへの登録手順
### 1.Githubからリポジトリを作成する。

### 2.順にコマンドを実行する。

```bash
$ echo "# リポジトリ名" >> README.md
$ git init
$ git add README.md
$ git commit -m "first commit"
$ git branch -M main
$ git remote add origin git@github.com:自分のユーザー名/リポジトリ名.git
```

### 3.公開鍵を取得し設定する。

```bash
$ vi ~/.ssh/id_rsa.pub
```

その後、GitHubのsetting画面から「New SSH」で公開鍵をペーストします。

### 4.GitへPushする。

```bash
$ git push -u origin main
```

### 5.バック用ディレクトリとフロント用ディレクトリをGitに反映させる。

```bash
$ cd backend/
$ rm -rf .git
$ cd ..
$ cd frontend/
$ rm -rf .git
$ cd ..
$ git add .
$ git commit -m "バック用ディレクトリとフロント用ディレクトリをGitに反映"
$ git push origin main
```

# 参考
[Ruby on Rails 7 with Bootstrap on Docker Compose 開発環境を簡単に構築する方法](https://qiita.com/normalsalt/items/8bf6c5010c9e9f127582)

[Next.js + Ruby on Rails(APIモード) on Docker 構築手順](https://zenn.dev/taku1115/articles/6c9fa97ab37e38)