Rails API/Next.js/PostgreSQL/Docker/Fly.io/Vercel
参考記事
フロントエンド・バックエンドディレクトリのサブモジュール化
├── rails-api-nextjs-verification-app
├── front
└── back
- メインリポジトリを作成。
- front/backディレクトリのリポジトリ作成。
- サブモジュール追加
rails-api-nextjs-verification-app $ git submodule add [フロントエンドリポジトリのURL] front
rails-api-nextjs-verification-app $ git submodule add [バックエンドリポジトリのURL] back
- メインリポジトリ変更のコミットとプッシュ
rails-api-nextjs-verification-app $ git add .
rails-api-nextjs-verification-app $ git commit -m "Add: submolues"
[submodule "front"]
path = front
url = [フロントエンドリポジトリのURL]
[submodule "back"]
path = back
url = [バックエンドリポジトリのURL]
バックエンド側作成
Docker環境構築
├── rails-api-nextjs-verification-app
├── front/
└── back/
├── docker-compose.yml
- ルートディレクトリにdocker-compose.ymlを配置する。
version: "3"
services:
db:
image: postgres:latest
environment:
POSTGRES_DB: app_development
POSTGRES_USER: user
POSTGRES_PASSWORD: password
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
back:
build:
context: ./back
dockerfile: Dockerfile
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -b '0.0.0.0'"
volumes:
- ./back:/app
ports:
- "3000:3000"
depends_on:
- db
tty: true
stdin_open: true
front:
build:
context: ./front/
dockerfile: Dockerfile
volumes:
- ./front:/app
command: yarn dev -p 4000
ports:
- "8000:4000"
volumes:
postgres_data:
Dokerfile作成
├── rails-api-nextjs-verification-app
├── front/
├── Dockerfile
└── back/
├── Dockerfile
├── docker-compose.yml
FROM ruby:3.2.2
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN gem install bundler
RUN bundle install
COPY . /app
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3002
CMD ["rails", "server", "-b", "0.0.0.0"]
#!/bin/bash
set -e
rm -f /app/tmp/pids/server.pid
exec "$@"
FROM node:19.4.0
WORKDIR /app
- Gemfile作成
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby "3.2.2"
gem "rails", "~> 7.0.5"
- Gemfile.lock作成(空)
├── rails-api-nextjs-verification-app
├── front/
├── Dockerfile
└── back/
├── Dockerfile
├── Gemfile
├── Gemfile.lock
├── docker-compose.yml
$ docker-compose build
Next.jsアプリ作成
エラー
% docker-compose run --rm front yarn create next-app .
yarn create v1.22.19
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Installed "create-next-app@14.0.3" with binaries:
- create-next-app
[##] 2/2The directory app contains files that could conflict:
Dockerfile
Either try using a new directory name, or remove the files listed above.
error Command failed.
Exit code: 1
Command: /usr/local/bin/create-next-app
Arguments: .
Directory: /app
Output:
info Visit https://yarnpkg.com/en/docs/cli/create for documentation about this command.
原因は、frontディレクトリ内のDockerfileとappディレクトリが競合していたため。Dockerfileを一時的に、ルートディレクトリへ移動した。
$ docker-compose run --rm front yarn create next-app .
$ docker-compose up front
Rails APIモード環境構築
docker-compose run --rm --no-deps back bundle exec rails new . --api --database=postgresql
config/application.rbに以下を追加
config.time_zone = 'Tokyo'
config.active_record.default_timezone = :local
config.i18n.default_locale = :ja
config/environments/development.rbに以下を記述することで、指定されたホスト名からのリクエストを許可することができます。
Rails.application.configure do
・・・
config.hosts << "api"
end
データベースのセットアップ
default: &default
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: user
password: password
host: db
docker-compose run --rm back rails db:create
% docker-compose run --rm back rails db:create
[+] Running 14/14
✔ db 13 layers [⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿] 0B/0B Pulled 36.5s
✔ 31ce7ceb6d44 Pull complete 16.8s
✔ 28caef79f6ed Pull complete 16.8s
✔ be24e278ddaa Pull complete 16.9s
✔ dfdbb4d6f9a3 Pull complete 17.0s
✔ ebb06cfd45ec Pull complete 17.2s
✔ 9738a56db3f9 Pull complete 17.3s
✔ 87cb08d2765c Pull complete 17.3s
✔ d99960ffd545 Pull complete 17.4s
✔ 4323262571df Pull complete 30.6s
✔ b0626670078e Pull complete 30.6s
✔ 1ee7ca4fb425 Pull complete 30.7s
✔ eb3cb400d64e Pull complete 30.7s
✔ f6218791bc49 Pull complete 30.8s
[+] Running 1/1
✔ Container rails-api-nextjs-verification-app-db-1 Created 0.5s
[+] Running 1/1
✔ Container rails-api-nextjs-verification-app-db-1 Started 0.3s
Could not find pg-1.5.4, puma-5.6.7, bootsnap-1.17.0, debug-1.8.0, msgpack-1.7.2, irb-1.9.1, reline-0.4.0, rdoc-6.6.0, psych-5.1.1.1, stringio-3.0.9 in locally installed gems
Run `bundle install --gemfile /app/Gemfile` to install missing gems.
$ docker-compose run --rm back bundle install
$ docker-compose build back
docker-compose run --rm back rails db:create
docker-compose up
API作成
scaffold追加
docker-compose run --rm back bundle exec rails g scaffold post title:string
docker-compose run --rm back bundle exec rails db:migrate
# seeds.rb
Post.create!(
[
{ title: '野球のルール基礎知識' },
{ title: 'プロ野球選手のトレーニング方法' },
{ title: '野球の歴史とは' },
{ title: 'メジャーリーグと日本プロ野球の違い' },
{ title: '野球用具の選び方' },
{ title: '野球のポジション紹介' },
{ title: '野球の戦術入門' },
{ title: '子供向け野球教室の選び方' },
{ title: '高校野球の魅力' },
{ title: '野球観戦の楽しみ方' },
{ title: '野球のスコアブックのつけ方' },
{ title: '野球の審判の役割' },
{ title: '野球におけるピッチングの技術' },
{ title: 'バッティングの基本' },
{ title: '野球の名言集' },
{ title: '野球のトレーニング用品紹介' },
{ title: '野球選手の食事管理' },
{ title: '野球の怪我の予防と対処法' },
{ title: '野球の上達法' },
{ title: '野球の国際大会について' }
]
)
docker-compose run --rm back bundle exec rails db:seed
rack-cors追加
gem "rack-cors"
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins 'localhost:8000', '127.0.0.1:8000'
resource "*",
headers: :any,
methods: [:get, :post, :put, :patch, :delete, :options, :head]
end
end
docker-compose run --rm back bundle install
再ビルド
docker-compose build back
Next.jsをVercelへデプロイする
frontリポジトリをVercelと連携させる。
RailsをFly.ioにデプロイする
- backディレクトリで、fly launchを実行。
- 以下のエラー発生。
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
An error occurred while installing pg (1.5.4), and Bundler cannot
continue.
In Gemfile:
pg
Error: Failed to install bundle, exiting: exit status 5
↑ brew install postgresql
で解決。
fly deploy
fly apps open
GithubActions
Vercel
- VercelのToken取得
- VercelCLI
Fly.io
372761 GB/s × VM: Additional RAM (at $0.00000193 / month)と1287 GB/hr × Volume: SSD Storage (at $0.0002083333 / month)の料金が発生してしまった。
無料枠
- 最大 3 つの共有 CPU-1x 256mb VM
- 3 GB 永続ボリューム ストレージ (合計)
- 160GBの送信データ転送
372761 GB/s × VM: Additional RAM (at $0.00000193 / month)
仮想マシン(VM)で使用された追加RAM(ランダムアクセスメモリ)に対する請求です。
-
まず、仮想マシン(VM)ってなんだ
- 物理的なハードウェア上で仮想的に作成されるコンピューターシステムです。一つの物理サーバー上で複数のVMを実行することができます。
- ビル全体がハードウェアを表すと、各オフィスが1つのVMに相当する。
-
RAM(ランダムアクセスメモリ)ってなんだ
- データを一時的に保存し、高速にアクセスするためのメモリです。
- オフィスの机に相当します。机が大きければ作業領域が広くなり、効率が向上するイメージです。
Fly.ioでは、無料枠で使用できるVM(最大3つの共有CPU VM)とRAM(256MBまで)のサイズが決まっており、なぜかその枠を超えてしまっていたみたいです。
今回のRailsAPIアプリケーションでは、どこでRAMを使用していたのか。
- データベース操作、リクエストの処理、アプリケーションロジックの実行などがRAMを消費するみたいです。
- PostgreSQLデータベースもまた、データの保存、クエリの実行、キャッシュ管理などにRAMを使用するみたいです。
- Dockerコンテナのリソースも関係あるみたい。
余分なRAMの使用量が原因っぽい。余分なRAMの使用量を削減する。
もう一度、デプロイしてみる。
$ fly launch
Memory & CPU
→VM Sizes
= shared-cpu-1x、VM Memory
=256MB
Database
→Configuration
=Development - Single node, 1x shared CPU, 256MB RAM 1GB disk
Fly.ioへのデプロイが失敗する
Fly.ioで設定されているアプリケーションの機械(マシン)の最大数に達したため発生している。
-------
✖ [1/2] Machine 148e441fd52989 [app] update failed: failed to update VM 148e441fd52989: You have reached the maximum number of machines for this app…
[2/2] Waiting for job
-------
Error: failed to update VM 148e441fd52989: You have reached the maximum number of machines for this app.
fly machine list
fly machine destroy [id]