Edited at

Rails on Docker(alpine)でAPIコンテナをつくってみた


はじめに

RailsにはAPIモードが存在します。バックエンド側でRailsを使いたい場合に便利そう。

この記事のGoalは、Rails on DockerでAPIコンテナを構築することにします。DBはPostgreSQLを利用します。最後にcurlでちゃんとAPIとして使えるかテストもしておきます。

dockerdocker-composeは準備済みの前提です。


ゴール


  • Rails on Docker(APIモード)を構築する

  • curlでAPIが正常に動作するかテストする


目次


  1. Rails on Dockerの下準備

  2. rails newでAPIアプリの作成

  3. 【TEST】 CRUDをテストしてみる


1. Rails on Dockerの下準備

まずはDockerfileを作っていきます。「Quickstart: Compose and Rails | Docker Documentation」でも書かれているように


  • Dockerfile

  • docker-compose.yml

  • Gemfile

  • Gemfile.lock

あたりを用意します。これらのファイルは作成するアプリのルートディレクトリにおいときます。


Dockerfile

FROM ruby:2.6.3-alpine3.10

ENV RUNTIME_PACKAGES="linux-headers libxml2-dev make gcc libc-dev nodejs tzdata postgresql-dev postgresql" \
DEV_PACKAGES="build-base curl-dev" \
HOME="/app_name" \
LANG=C.UTF-8 \
TZ=Asia/Tokyo

WORKDIR $HOME

ADD Gemfile $HOME/Gemfile
ADD Gemfile.lock $HOME/Gemfile.lock

RUN apk update && \
apk upgrade && \
apk add --update --no-cache $RUNTIME_PACKAGES && \
apk add --update --virtual build-dependencies --no-cache $DEV_PACKAGES && \
bundle install -j4 && \
apk del build-dependencies

ADD . $HOME

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


imageの軽量化をめざしてalpine使っちゃってます。


docker-compose.yml

version: "3"

services:
db:
container_name: app_name_db
image: postgres:11.4-alpine

app:
container_name: app_name_app
build: .
volumes:
- .:/app_name
ports:
- 3000:3000
depends_on:
- db


こちらもPostgreSQLをalpineで。


Gemfile

source 'https://rubygems.org'

gem 'rails', '~>5'

Gemfileはこんな感じで。

Gemfile.lockはファイルを作っておくだけ。

$ touch Gemfile.lock


2. rails newでAPIアプリの作成

$ docker-compose run app rails new . -f -d postgresql --api

ポイントは--apiの部分です。このオプションをつけることでapiアプリに不要なものが生成されなくなります。

あとはDB作成しておきます。


config/database.yml

#####

default: &default
adapter: postgresql
encoding: unicode
host: db # add
username: postgres # add
password: # add
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
#####

$ docker-compose build

$ docker-compose run --rm app rails db:create
$ docker-compose up -d

http://localhost:3000にアクセスしていつものRails Hello Worldページが出たら成功です。

image.png

このページは表示されますが、APIモードでアプリを作っているので他のviewをつくるのは面倒です。scaffoldしてもviewができたりはしないです。

一旦コンテナ停止しときます。

$ docker-compose down


3. 【TEST】 CRUDをテストしてみる

テスト用に適当にモデルを作ってみます。nameをもつUserモデルにします。

$ docker-compose run --rm app rails generate scaffold user name:string

$ docker-compose run --rm app rails db:migrate
$ docker-compose up -d


3-1. Create

$ curl -X POST http://localhost:3000/users -d 'user[name]=test1'

{"id":1,"name":"test1","created_at":"YYYY-MM-DD","updated_at":"YYYY-MM-DD"}

$ curl -X POST http://localhost:3000/users -d 'user[name]=test2'
{"id":2,"name":"test2","created_at":"YYYY-MM-DD","updated_at":"YYYY-MM-DD"}

おー、ユーザーできた。


3-2. Read

$ curl -X GET http://localhost:3000/users

[{"id":1,"name":"test1","created_at":"YYYY-MM-DD","updated_at":"YYYY-MM-DD"},{"id":2,"name":"test2","created_at":"YYYY-MM-DD","updated_at":"YYYY-MM-DD"}]

$ curl -X GET http://localhost:3000/users/1
{"id":1,"name":"test1","created_at":"YYYY-MM-DD","updated_at":"YYYY-MM-DD"}

indexの取得もshowの取得もできたぜ。ちなみにGETの場合は-X GETオプションはなくてもOK。


3-3. Update

$ curl -X PUT http://localhost:3000/users/1 -d 'user[name]=test3'

{"id":1,"name":"test3","created_at":"YYYY-MM-DD","updated_at":"YYYY-MM-DD"}

id=1のユーザーのnametest1からtest3にアップデートされましたー。


3-4. Delete

$ curl -X DELETE http://localhost:3000/users/1

$ curl -X GET http://localhost:3000/users
{"id":2,"name":"test2","created_at":"YYYY-MM-DD","updated_at":"YYYY-MM-DD"}

id=1のユーザーが消えました!


Reference