RailsとNuxt3でtodoリストを作ろう[REST-API/Terraform/Fargate]〜その１、Rails基本設定編

# はじめに

RailsとNuxt3でtodoリストの作り方を
初めから丁寧に説明したいと思います。

使用pcはmacを想定しています。

完成した構成図は以下の通りです。

![aws_structure.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731268/362a1ef8-00e1-75d0-e923-ad2e59eca033.png)


また、githubレポジトリはこちらです。

https://github.com/sugiyama404/ruby_and_nuxt

各シリーズは以下の通りです。

[RailsとNuxt3でtodoリストを作ろう[REST-API/Terraform/Fargate]〜その１、Rails基本設定編](https://qiita.com/sugiyama404/items/637900df3b533fd149f8)
[RailsとNuxt3でtodoリストを作ろう[REST-API/Terraform/Fargate]〜その２、Rails API編](https://qiita.com/sugiyama404/items/acea4cc38fe7f155ab54)
[RailsとNuxt3でtodoリストを作ろう[REST-API/Terraform/Fargate]〜その３、Nuxt.js編](https://qiita.com/sugiyama404/items/4e74c4446add5efc3669)
[RailsとNuxt3でtodoリストを作ろう[REST-API/Terraform/Fargate]〜その４、TerraformECS前編](https://qiita.com/sugiyama404/items/4e19ac1f9be6b8213f55)
[RailsとNuxt3でtodoリストを作ろう[REST-API/Terraform/Fargate]〜その５、TerraformECS後編](https://qiita.com/sugiyama404/items/d0e0e74628d38842c9bd)
[RailsとNuxt3でtodoリストを作ろう[REST-API/Terraform/Fargate]〜その６、Blue/Greenデプロイ前編](https://qiita.com/sugiyama404/items/1ffb4334b3a1546b4e23)
[RailsとNuxt3でtodoリストを作ろう[REST-API/Terraform/Fargate]〜その７、Blue/Greenデプロイ後編](https://qiita.com/sugiyama404/items/ea57e8c08156bf6eca46)


# Railsを環境構築してみよう。

ここら辺参考にしてます。

https://railsguides.jp/api_app.html

## Dockerをbuildしてみる。

dockerhubから最新のrubyのバージョンを調べてDockerfileに書きましょう。

https://hub.docker.com/_/ruby

Dockerfileは本番用と練習用で分ける予定ですが、最初なのでDockerfileのままで書きます。

```text:現在のファイル構成
.
├── apserver
│   └── Dockerfile
├── docker-compose.yml
```

g++とmakeとgitはrailsをinstallする時に必要。
ないと、エラーが出ます。

```Dockerfile
FROM ruby:3.1.3-slim-buster

WORKDIR /usr/src

RUN apt-get update \
    && apt-get install -y --no-install-recommends \
    g++=4:8.3.0-1 make=4.2.1-1.2 \
    libmariadb-dev=1:10.3.38-0+deb10u1 \
    git=1:2.20.1-2+deb10u8 \
    && apt-get -y clean \
    && rm -rf /var/lib/apt/lists/*
```


Docker-compose.ymlのttyを設定しておくと、コンテナを起動し続けてくれます。
volumesは永続化と言って、コンテナ内のディレクトリーをホストPC内に写し操作することができます。

```yml:Docker-compose.yml
version: "3"
services:
  apserver:
    build: ./apserver
    container_name: "ruby"
    tty: true
    volumes:
      - ./apserver:/usr/src/myapp
    ports:
      - "8080:8080"
```

docker compose upをすると、一番最初はdocker buildも一緒にやってくれます。
docker compose upで仮想環境を立ち上げてみましょう。
では、実行してみましょう。

```console
docker compose up
```

## Railsのインストール

以下のコマンドを打ち、コンテナ内に入って見ましょう。

apserverはDocker-compose.ymlに記載してあるサービス名です。


```console
docker compose exec apserver bash
```

```console
gem install rails -v 7.0.4.2
```

appはアプリケーション名です。好きな名前に変えてok。

```console
rails new app --api -f
cd app
rails s -b 0.0.0.0
```

http://localhost:3000

にアクセスしてみましょう。

![Screenshot 2023-03-10 at 19.49.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731268/55700ecc-63dc-ee14-bb73-9a1198ac1d0e.png)

# jsonを受け取ろう。

以下のコマンドで自動でコントローラが作られます。

```console
rails g controller index
```


```ruby:config/routes.rb
Rails.application.routes.draw do
  root "index#index"
end
```

```ruby:controllers/index_controller.rb
class IndexController < ApplicationController
    def index
        render json: { status: 'SUCCESS', message: 'hello world!!!' }
      end
end
```

```ruby:view/index/index.html.rb
<!DOCTYPE html>
<html>
  <head>
  </head>

  <body>
    <h1>hi</h1>
  </body>
</html>
```

http://localhost:3000/

にアクセスしてみましょう。

![Screenshot 2023-03-10 at 20.45.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731268/7fc88724-fcf1-b5d3-b885-5c044afbbd88.png)

![Screenshot 2023-03-10 at 20.47.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731268/47a9503f-37f4-1bf7-70e2-41311363273a.png)

# Rspecでテストを実施してみよう

まずはインストール

```console
sed -i -e '$ a gem "rspec-rails", "~> 6.0.1"' ./Gemfile
bundle install
```
テストを生成します。

```console
rails g rspec:request index
```

```ruby:spec/requests/indices_spec.rb
require 'rails_helper'

RSpec.describe "Indices", type: :request do
  describe "GET /" do
    it "works! (now write some real specs)" do
      get '/'
      expect(response).to have_http_status(200)
    end
  end
end
```

テストを実行してみよう。

```console
bundle exec rspec
```

![Screenshot 2023-03-26 at 14.01.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731268/5bc36b24-ccce-4ee9-b063-a8f4af37f683.png)


# Github actionsでテストを実行してみよう

Dockerfileをテストが実行できるように書き換えます。
ENVはfargateでdb接続するために書いています。

```Dockerfile
FROM ruby:3.1.3-slim-buster

WORKDIR /usr/src

ENV HOST dbserver
ENV DBNAME todoproject
ENV USERNAME rubyMySql1
ENV PASSWORD rubyMySql1

RUN apt-get update \
    && apt-get install -y --no-install-recommends \
    g++=4:8.3.0-1 make=4.2.1-1.2 \
    libmariadb-dev=1:10.3.38-0+deb10u1 \
    mariadb-client=1:10.3.38-0+deb10u1 \
    git=1:2.20.1-2+deb10u8 \
    && apt-get -y clean \
    && rm -rf /var/lib/apt/lists/*

COPY . .
WORKDIR /usr/src/app
RUN bundle install
```

GitHubActionsでテストを実行するために以下のファイルを作ります。



```yml:.github/workflows/app.test-deploy.yml
name: "Test and deploy the application"

on:
  push:
    branches: ["main"]
    paths:
      - apserver/**
      - .github/workflows/**
  workflow_dispatch:

defaults:
  run:
    shell: bash

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Build the Docker image
        run: docker compose up -d
      - name: unit test
        run: |
          docker compose exec apserver bundle exec rspec
      - name: Docker Down
        run: docker compose down
```

GitHubに移動し
成功すると以下の画面になります。

![Screenshot 2023-03-26 at 15.13.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731268/056a0cdc-52ad-f3b8-b9d9-d0e023b3bf0d.png)




# データベースに接続してみよう

## docker-compose.ymlにmysqlを追加してみよう

```Dockerfile:dbserver/Dockerfile
FROM mysql:8.0.32-debian

RUN apt-get update \
    && apt-get install -y locales \
    && sed -i -E 's/# (ja_JP.UTF-8)/\1/' /etc/locale.gen \
    && locale-gen \
    && update-locale LANG=ja_JP.UTF-8 \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*
ENV LC_ALL ja_JP.UTF-8
```

```yml:Docker-compose.yml
  dbserver:
    build: ./dbserver
    container_name: mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: todoproject
      MYSQL_USER: rubyMySql1
      MYSQL_PASSWORD: rubyMySql1
      TZ: 'Asia/Tokyo'
    command: mysqld
    volumes:
      - ./dbserver/conf/my.cnf:/etc/mysql/conf.d/my.cnf
    ports:
      - 3306:3306
```

```conf:dbserver/conf/my.cnf
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci

# mysql8.xからデフォルト認証プラグインの設定が必要
default-authentication-plugin = mysql_native_password

[mysql]
default-character-set = utf8mb4

[client]
default-character-set = utf8mb4
```


## クライアントツールを使いmysqlの接続を確認しよう

![Screenshot 2023-03-26 at 15.54.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731268/91f87ee9-30db-74b0-4b52-450119d80d71.png)


## railsからdb接続しよう

```console
sed -i -e '$ a gem "mysql2", "~> 0.5.5"' ./Gemfile
bundle install
```

コンテナの中に入り接続を確認してみましょう。

```console
rails dbconsole
```
![Screenshot 2023-03-26 at 19.36.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/731268/19365b0c-2b9d-451f-738d-de6056b46821.png)