##初めに
最近はDockerとRailsのAPIモードを学習してるので、
学んだことをまとめてメモしておきます。
##まずはDocker環境構築から
Dockerの環境構築は主に以下の記事の参考で作成していきます。
最初はまず作業用のファイルを用意します
$ mkdir myapp
###Dockerfile作成
rubyのバージョンは自分が今使ってる2.7.2に変更してみます。
FROM ruby:2.7.2
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
RUN apt-get update && apt-get install -y curl apt-transport-https wget && \
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
apt-get update && apt-get install -y yarn
RUN curl -sL https://deb.nodesource.com/setup_7.x | bash - && \
apt-get install nodejs
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp
# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]
P.S.Docker 入門 1項目ずつ理解するでは、Dockerfileの書き方について分かりやすく説明していますので、是非ご参考ください。
###Gemfile作成
source 'https://rubygems.org'
gem 'rails', '~> 6'
Gemfile.lock 作成
$ touch Gemfile.lock
中身は空のままでオッケー
entrypoint.sh作成
$ touch entrypoint.sh
#!/bin/bash
set -e
# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid
# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
###docker-compose.yml 作成
$ touch docker-compose.yml
version: "3.9"
services:
db:
image: postgres
volumes:
- ./tmp/db:/var/lib/postgresql/data
environment:
POSTGRES_HOST_AUTH_METHOD: 'trust'
web:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/myapp
ports:
- "3000:3000"
depends_on:
- db
###これで下準備完了
ファイルの中はこんな感じ:
myapp
- Dockerfile
- Gemfile
- Gemfile.lock
- entrypoint.sh
- docker-compose.yml
###いよいよRails new
今回RailsのAPI開発モードを利用していますので、--api
オプションを使います。
-T
はデフォルトのテスティングフレームワーク「Minitest」をオフにするオプションです。
APIモード使わない場合は--api
を自由に削除してください。
$ docker-compose run web rails new . --force --no-deps --database=postgresql --api -T
ls -l
コマンドでみると。。。
$ ls -l
total 64
-rw-r--r-- 1 tsuki_ staff 831 Apr 24 23:02 Dockerfile
-rw-r--r-- 1 tsuki_ staff 1397 Apr 24 23:48 Gemfile
-rw-r--r-- 1 tsuki_ staff 4022 Apr 24 23:48 Gemfile.lock
-rw-r--r-- 1 tsuki_ staff 374 Apr 24 23:48 README.md
-rw-r--r-- 1 tsuki_ staff 227 Apr 24 23:48 Rakefile
drwxr-xr-x 8 tsuki_ staff 256 Apr 24 23:48 app
drwxr-xr-x 7 tsuki_ staff 224 Apr 24 23:48 bin
drwxr-xr-x 16 tsuki_ staff 512 Apr 24 23:48 config
-rw-r--r-- 1 tsuki_ staff 160 Apr 24 23:48 config.ru
drwxr-xr-x 3 tsuki_ staff 96 Apr 24 23:48 db
-rw-r--r-- 1 tsuki_ staff 366 Apr 24 23:29 docker-compose.yml
-rw-r--r-- 1 tsuki_ staff 201 Apr 24 23:23 entrypoint.sh
drwxr-xr-x 3 tsuki_ staff 96 Apr 24 23:48 lib
drwxr-xr-x 3 tsuki_ staff 96 Apr 24 23:48 log
drwxr-xr-x 3 tsuki_ staff 96 Apr 24 23:48 public
drwxr-xr-x 3 tsuki_ staff 96 Apr 24 23:48 storage
drwxr-xr-x 7 tsuki_ staff 224 Apr 24 23:48 tmp
drwxr-xr-x 3 tsuki_ staff 96 Apr 24 23:48 vendor
無事にRailsが生成されてますね!
###bundle install
$ docker-compose build
ぬぬ!?エラーが出ました
...[前略]
------
> [ 9/12] RUN bundle install:
#14 0.294 /usr/local/lib/ruby/2.7.0/rubygems.rb:277:in `find_spec_for_exe': Could not find 'bundler' (1.17.2) required by your /myapp/Gemfile.lock. (Gem::GemNotFoundException)
#14 0.294 To update to the latest version installed on your system, run `bundle update --bundler`.
#14 0.294 To install the missing version, run `gem install bundler:1.17.2`
#14 0.296 from /usr/local/lib/ruby/2.7.0/rubygems.rb:296:in `activate_bin_path'
#14 0.296 from
------
...[後略]
run `gem install bundler:1.17.2`
と書いたので、追加してみます。
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
########追加###########
RUN gem install bundler:1.17.2
######################
RUN bundle install
COPY . /myapp
はい、$ docker-compose build
ぬぬ!?また新しいエラーが出てきました。
...[前略]
------
> [10/13] RUN bundle install:
#14 0.734 Your Ruby version is 2.7.2, but your Gemfile specified 2.6.5
------
...[後略]
そっか、GemfileのRubyバージョンは2.6.5だったのか
はい、変更!
#変更前
ruby '2.6.5'
#変更後
ruby '2.7.2'
。。。
はい、$ docker-compose build
!
...[前略]
Successfully built.....
...[後略]
今度こそ無事にできたんですね!
###DBへの接続設定
Railsのconfig/database.yml
ファイルを、下記のように書き換えます。
default: &default
adapter: postgresql
encoding: unicode
host: db
username: postgres
password:
pool: 5
development:
<<: *default
database: myapp_development
test:
<<: *default
database: myapp_test
###Dockerコンテナの起動
では、Dockerを起動してみます。
$ docker-compose up
したら、安心する画面ができましたね!
...[前略]
web_1 | => Booting Puma
web_1 | => Rails 6.1.3.1 application starting in development
web_1 | => Run `bin/rails server --help` for more startup options
web_1 | Puma starting in single mode...
web_1 | * Puma version: 5.2.2 (ruby 2.7.2-p137) ("Fettisdagsbulle")
web_1 | * Min threads: 5
web_1 | * Max threads: 5
web_1 | * Environment: development
web_1 | * PID: 1
web_1 | * Listening on http://0.0.0.0:3000
web_1 | Use Ctrl-C to stop
http://0.0.0.0:3000
にアクセスしてみると
ぬぬ!?またエラーの画面が出てきました。
...[前略]
web_1 | ActiveRecord::NoDatabaseError (FATAL: database "myapp_development" does not exist
web_1 | ):
...[後略]
そかそかdatebaseの問題ね!
では一旦
$ docker-compose down
P.s.筆者はもう一つターミナルを開いて実行していますが、
こちらの【Docker超入門 #7】Docker ComposeでRailsを構築しようの19:55からのところは、
docker-compose up
をバックグラウンドで実行してくれることについて説明がありますので、
必要な方は是非参考してみてください。
###DB作成
$ docker-compose run web rails db:create
そして
$ docker-compose up
無事に環境構築できたそうですね!!
##Dockerの環境でAPIモードでAPIを作ってみよう
この記事の参考で、Docker内でAPIを作っていきます。
###テスト環境
まずはテスト環境を先に用意していきます。今回はRspecを使います。
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
#⇩追加
gem 'rspec-rails'
end
そしてdocker-compose build
でbundle install
次はこちらの記事:dockerでよく使うコマンド一覧【Rails】で学んだDockerのコマンドで
Rspecのインストールを行います。
$ docker-compose run web bundle exec rails g rspec:install
それでspecファイルが生成されます。
###モデル.コントローラの作成
では今回は簡単なタスク機能のアプリを作っていきます。
$ docker-compose run web bundle exec rails g model post title:string content:text
$ docker-compose run web bundle exec rails g controller posts
$ docker-compose run web bundle exec rails db:create
$ docker-compose run web bundle exec rails db:migrate
###ルーティングの設定
Rails.application.routes.draw do
namespace 'api' do
namespace 'v1' do
resources :posts
end
end
end
###コントローラの設定
ルートで設定した名前空間に合わせてディレクトリの構成を以下のようにします。
module Api
module V1
class PostsController < ApplicationController
before_action :set_post, only: [:show, :update, :destroy]
def index
posts = Post.order(created_at: :desc)
render json: { status: 'SUCCESS', message: 'Loaded posts', data: posts }
end
def show
render json: { status: 'SUCCESS', message: 'Loaded the post', data: @post }
end
def create
post = Post.new(post_params)
if post.save
render json: { status: 'SUCCESS', data: post }
else
render json: { status: 'ERROR', data: post.errors }
end
end
def destroy
@post.destroy
render json: { status: 'SUCCESS', message: 'Deleted the post', data: @post }
end
def update
if @post.update(post_params)
render json: { status: 'SUCCESS', message: 'Updated the post', data: @post }
else
render json: { status: 'SUCCESS', message: 'Not updated', data: @post.errors }
end
end
private
def set_post
@post = Post.find(params[:id])
end
def post_params
params.require(:post).permit(:title,:content)
end
end
end
end
###初期データ作成
今回はseedで作ってみます。
seedの書き方はこの記事の参考しています→railsのseedの書き方いろいろ
15.times do |i|
Post.create!(
title: "title#{i+1}",
content: "テキスト#{i+1}" * 10
)
end
seed書いたら
$ docker-compose run web rails db:seed
エラーが出ないので、無事にできたようです。
##postmanを使用して動作の確認
データはseedで生成したので
Railsのサーバーを動かしてみます。
$ docker-compose up
次はPostmanを開きます。
###GET
まずはGETの方にhttp://localhost:3000/api/v1/posts
、もしくは http://0.0.0.0:3000/api/v1/posts
と記述していきます。
下の方にidの1〜15番のデータを取得することができました。
今度はid
を指定します。
###POST
次はデータ作成してみましょう。
JSON
のデータ形式で渡します。
Sendするとちゃんとid16が表示されました。
###PUT
今回はURLをidを16に指定します
http://0.0.0.0:3000/api/v1/posts/16
登録したデータをupdate更新してみます。
PUT
の選択とJSON
形式の設定を忘れないように
###DELETE
最後に削除(Destroy)してみます。
同じURLをidを16に指定します
http://0.0.0.0:3000/api/v1/posts/16
DELETE
の選択で実行すれば、
無事に削除できたようですね
##まとめ
以上、Dockerの環境構築+RailsのAPIモードのまとめでした。
今回Rspecのテストは書かないのですが、
こちらの記事:【Rails】APIテストの書き方がありますので、興味がある方はご参考ください
もし内容の誤りがありましたら、ご指摘いただければ幸いです。
最後まで読んでいただき、ありがとうございました。