Rails API + Postgresql の環境を Docker で構築する
Docker
を用いて、Ruby on Rails
API モードの開発環境の構築を行っていきます。
サンプル API を作成し、疎通確認するところまでやります。DB は作成しますがこの記事では使いません。
サンプルプロジェクト
ディレクトリ構造
こんな感じでプロジェクトディレクトリに空のファイル群を作成しておきます。
.
├─ compose.yml
└─ rails
├─ Dockerfile
├─ Gemfile
├─ Gemfile.lock
└─ entrypoint.sh
compose.yml などの準備
compose.yml
で、postgres
を使用した API を作成する別記事を公開する関係でデータベースに postgres
を使用していますが、任意で大丈夫です。
Gemfile.lock
は空のままで大丈夫です。
entrypoint.sh
には、サーバーのプロセスが残っている場合、新たにサーバーを起動できないため、それを防ぐために起動時にプロセスをいったん削除するコマンドが記述されています。
compose.yml
version: '3'
services:
db:
container_name: postgres-sample
image: postgres:16.0
ports:
- "5432:5432"
volumes:
- pg-data:/var/lib/postgresql/data
environment:
- POSTGRES_DATABASE=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=password
- POSTGRES_ROOT_PASSWORD=root
api:
container_name: api-sample
build:
context: ./rails
command: bash -c "rails s -b '0.0.0.0'"
volumes:
- ./rails:/usr/src/app
ports:
- 3000:3000
depends_on:
- db
tty: true
stdin_open: true
volumes:
pg-data:
bin:
driver: local
Dockerfile
FROM ruby:3.3.0
RUN apt-get update -qq && apt-get install -y vim
RUN mkdir /usr/src/app
WORKDIR /usr/src/app
COPY Gemfile /usr/src/app/Gemfile
COPY Gemfile.lock /usr/src/app/Gemfile.lock
RUN gem update --system
RUN bundle update --bundler
RUN bundle install
COPY . /usr/src/app
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
Gemfile
source "https://rubygems.org"
git_source(:github) {|repo| "https://github.com/#{repo}.git" }
ruby "3.3.0"
gem "rails", "~> 7.1.2"
entrypoint.sh
#!/bin/bash
set -e
rm -f /usr/src/app/tmp/pids/server.pid
exec "$@"
Rails アプリの作成
下記コマンドを実行して、Rails
アプリケーションを作成します。
docker compose run --rm api rails new . --skip --database=postgresql --api --skip-bundle
各オプションについて
各オプションやその他のオプションについてはこちらから確認することができます。
オプション | 説明 |
---|---|
. | ディレクトリ直下にプロジェクトを作成 |
--force | ファイルが存在する場合上書き |
-skip | ファイルが存在する場合スキップ |
--database | データベースを指定 |
--api | API のみでアプリを作成 |
--skip-bundle | bundle install をスキップ |
Gemfile, database.yml を書き換える
以下のように Gemfile
を書き換えます。
また、config/database.yml
も作成した環境に合わせて書き換えます。
Gemfile
source "https://rubygems.org"
git_source(:github) {|repo| "https://github.com/#{repo}.git" }
ruby "3.3.0"
gem "bootsnap", require: false
gem "pg", "~> 1.1"
gem "puma", "~> 6.4.0"
gem "rails", "~> 7.1.2"
gem "tzinfo-data", platforms: %i[mingw mswin x64_mingw jruby]
config/database.yml
default: &default
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: postgres
password: password
host: db
port: 5432
development:
<<: *default
database: postgres_dev
password: password
test:
<<: *default
database: postgres_test
password: password
gem をインストールする
下記コマンドを実行して、gem をインストールします。
docker compose run --rm api bundle install
Docker コンテナを立ち上げる
コンテナをビルドして立ち上げます。
docker compose build --no-cache
docker compose up -d
Postgresql の DB を作成する
現状だと DB が存在しないため作成する必要があります。
rails
コンテナ環境に入ります。
docker compose exec api /bin/bash
rails
コンテナ内で db:create
して DB を作成します。
rails db:create
起動確認
下記にアクセスし、Rails
が動作していることを確認します。
localhost:3000
サンプル API を作成し、動作確認
簡易的な JSON を返すサンプル API を作成してみます。
rails
コンテナ内で下記コマンドを実行します。
コントローラーの作成
下記のようにコントローラーを実装します。
rails g controller status
status_controller.rb
class StatusController < ApplicationController
def index
render json: {message: "available."}, status: :ok
end
end
routes.rb の設定
route を設定します。
config/routes.rb
Rails.application.routes.draw do
get "status", to: "status#index"
end
疎通確認
上記通りの実装なら、下記 URL にアクセスします。
レスポンスが返ってくれば OK です。
localhost:3000/status
レスポンス
{"message":"available."}
さいごに
postgresql
を利用する場合は、rails db:create
する必要があることに気づかずちょいつまづいてしまいました。
参考
Discussion