15
14

More than 1 year has passed since last update.

Next.js×Rails APIモードのJSONを返すアプリをDockerで環境構築して作ってみた

Last updated at Posted at 2023-07-03

はじめに

フロントエンドをNext.js 13(TypeScript)、バックエンドをRuby on RailsのAPIモードで構成するアプリケーションをDockerで環境構築しJSONを返すアプリを作ってみました。

参考にしたもの

ディレクトリ構成

以下の通りになります。
コマンドもしくはGUI操作でディレクトリとファイルを作成してください。

next-rails
next-rails
├── backend
│   ├── Dockerfile
│   ├── Gemfile
│   └── Gemfile.lock
├── docker-compose.yml
└── frontend
    └── Dockerfile

Dockerを準備

docker-compose.ymlの作成

データベースはMySQLを採用しています

next-rails/docker-compose.yml
version: '3.8'

services:
  db:
    image: mysql:8.0
    command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: sample
      MYSQL_PASSWORD: password
    ports:
      - 4306:3306
    volumes:
      - mysql-db:/var/lib/mysql
  backend:
    tty: true
    depends_on:
      - db
    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:
  mysql-db:
    driver: local

フロントエンド(Next.js)のDockerfileの作成

frontend/Dockerfile
FROM node:18
WORKDIR /usr/src/app

バックエンド(Rails)のDockerfileの作成

backend/Dockerfile
FROM ruby:3.2

ENV LANG=C.UTF-8 \
  TZ=Asia/Tokyo

WORKDIR /app
RUN apt-get update -qq && apt-get install -y nodejs default-mysql-client
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN bundle install

CMD ["rails", "server", "-b", "0.0.0.0"]

Gemfileの作成

backend/Gemfile
source 'https://rubygems.org'
gem 'rails', '~> 7.0.5'

ビルドする

以上のファイルの準備ができたらビルドのコマンドを実行

docker compose build

Next.jsを作成する

yarn createfrontendディレクトリにNext.jsを作成する

docker compose run --rm frontend yarn create next-app .

アプリの生成が完了した後

以下コマンドでコンテナを起動

docker compose up

localhost:8000にアクセスしNext.jsの画面が表示されていれば成功です。
スクリーンショット 2023-06-25 16.58.09.png

Ruby on Rails APIモード環境の作成

backendディレクトリにRails APIモードのアプリを作成する

docker compose run --rm backend bundle exec rails new . --api -d mysql

生成途中でGemfileのConfilictが生じるがyを入力し進める

database.ymlの編集

Rails APIアプリケーションの作成が完了した後にdatabase.ymlを以下の通り編集する

backend/config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password  #passwordと設定
  host: db #localhostからdbに設定

development:
  <<: *default
  database: sample #app_developmentからsampleと設定

test:
  <<: *default
  database: app_test

production:
  <<: *default
  database: app_production
  username: app
  password: <%= ENV["APP_DATABASE_PASSWORD"] %>

Railsアプリを起動

docker compose up --build -d

localhost:3000にアクセスしてRailsの画面が表示されていれば成功です。
スクリーンショット 2023-06-25 17.13.04.png

JSONを返すAPIを作る

rails g scaffoldで必要なファイルを作成

docker compose run --rm backend bundle exec rails g scaffold post title:string

マイグレートする

POSTSテーブルが作成されます

docker compose run --rm backend bundle exec rails db:migrate

seeds.rbを編集

titleの部分にダミーテキストを入力

backend/db/seeds.rb
Post.create!(
    [
      {
        title: 'Lorem ipsum dolor sit amet.'
      },
      {
        title: 'Id velit nesciunt et adipisci vitae aut eligendi sunt eum minima totam.'
      },
      {
        title: 'Et cumque maiores eos voluptate tempore ut tempora dignissimos et soluta corrupti est nihil beatae.'
      },
      {
        title: 'Et commodi quam non dolorem quia ea cumque distinctio qui exercitationem voluptate cum iusto distinctio vel modi pariatur et doloremque officiis.'
      },
      {
        title: 'In saepe unde sed obcaecati similique quo beatae amet et Quis incidunt eos molestiae nobis et nihil tenetur?'
      },
    ]
  )

テーブルにテストデータを取り込む

docker compose run --rm backend bundle exec rails db:seed

localhost:3000/postsにアクセスしseeds.rbで入力したダミーテキストのJSONデータが表示されていれば成功です。

スクリーンショット 2023-07-02 16.40.25.png

Next.jsでAPIから取得したデータを表示する

development.rbを編集

backend/config/environments/development.rbconfig.hosts << "backend"を追加する

require "active_support/core_ext/integer/time"

Rails.application.configure do
・・・

+ config.hosts << "backend"
end

Page.tsxを編集

Tailwind CSSがデフォルト設定されているので多少カスタマイズしています。

frontend/app/app/page.tsx
import { FC } from 'react';

type Post = {
  id: number;
  title: string;
};

async function getPost() {
  const res = await fetch('http://backend:3000/posts');

  if (!res.ok) {
    throw new Error('Failed to fetch Post');
  }

  return res.json();
}

const Home: FC = async () => {
  const posts: Post[] = await getPost();

  return (
    <div className="m-4">
      <h1 className="text-4xl mb-4 underline">Post List</h1>
      {posts.map((post) => (
        <p className="mb-1" key={post.id}>
          {post.title}
        </p>
      ))}
    </div>
  );
};

export default Home;

完成

localhost:8000にアクセスして以下のように表示されていれば成功です。
スクリーンショット 2023-07-03 0.03.44.png

15
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
14