はじめに
まとめておくと後で楽だよねってことで
環境
Ruby 2.6.5p114
Rails 6.0.1
環境自体はDockerコンテナに押し込めているので、まずはDockerの設定周りからやっていきます。
Docker関連
docker-compose.yml
こちらの記事を参考にしつつ作成しています。
ENTRYPOINTは自分が理解しきれてないので指定していません。
なくても動きます。
後、重要なのはmysqlのvolumesとして/etc/mysql/conf.d
がいったん必須です。
mysql8からデフォルトの認証方式がパスワードになっていないので、それをパスワードにするために永続化して設定ファイルを入れてあげないと困ります。
認証方式変わったということは、それをデフォルトとして他を変えるのが本筋ですが、公開するサービスではないので、いったんパスワードにしています。
version: '3'
services:
db:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: password
ports:
- '13306:3306'
volumes:
- ./mysql:/var/lib/mysql
- ./mysql-confd:/etc/mysql/conf.d
rails:
build:
context: .
dockerfile: ruby/Dockerfile
command: bash -c "bundle exec rails s -p 3000 -b '0.0.0.0'"
environment:
- "DATABASE_HOST=db"
- "DATABASE_PORT=13306"
- "DATABASE_USER=root"
- "DATABASE_PASSWORD=password"
volumes:
- .:/app
ports:
- "13000:3000"
Dockerfile
こちらはRails6からwebpackerを入れる必要があるため、その設定は入れています。
今回はAPIを作るようのアプリケーションにするため、この設定はまるごといらないのですが、削除しなくても困らないので残しています。
APIモードで作らない場合はdocker-compose.ymlのcommandでインストールしてあげるかDockerfile内でインストールしてあげればOKです。
あと重要なのは最後にRUN bundle install
を入れておくぐらいでしょうか。
Gemを書き換えた際にはイメージを書き換えないと駄目っぽいのですが(本当か?)、これやっておかないと起動時にGemがないと言われて怒られます。
1個目の方はRails関連のGemを入れるようなので、別にやっておかないとアプリケーションの方のGemの読み直してくれません。
※
ここも色々参考にさせていただいた記事があるのですが、見つけ次第追記します。
どの記事だっけなぁ・・・
FROM ruby:2.6.5
ENV TZ='Asia/Tokyo'
RUN /bin/cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
ENV LANG C.UTF-8
RUN 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
RUN apt-get update -qq && apt-get install -y nodejs yarn
RUN gem install bundler
WORKDIR /tmp
ADD ruby/Gemfile Gemfile
ADD ruby/Gemfile.lock Gemfile.lock
RUN bundle install
ENV APP_HOME /app
RUN mkdir -p $APP_HOME
WORKDIR $APP_HOME
ADD . $APP_HOME
RUN bundle install
Gemfile
バージョンは適宜読み替えてください。
Gemfile.lockは参考にある通り空ファイルです。
Gemfileはrailsアプリケーションを生成した際に上書きされると困るので、rootフォルダとは別の場所に置いてあります。
source 'https://rubygems.org'
gem 'rails', '~> 6.0.1'
railsアプリケーションの生成
ファイルの準備が出来たらアプリケーションを生成します。
docker-compose run rails rails new . --api --force --no-deps --database=mysql
config/database.yml
立ち上げる前にデータベースの設定を書き換えます。
passwordとhostの書き換えだけです。
docker-composeでアプリケーションを作成するとネットワークをいい感じで作ってくれるため、hostをサービス名で設定しておけばいいので楽ですね。
docker-composeで設定したportsもこのネットワーク外部から繋いだ時のものでネットワーク内部からは普通のportで接続となります。
default: &default
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: root
password: password
host: db
database作成
rakeコマンド使うなり自力で作るなりしてDB作っておいてください。
docker起動
ビルドして起動します。
中々に時間がかかるので、間違えてやり直しをするのが結構辛かったです。
docker-compose build
docker-compose up -d
起動確認
localhost:13000
につないで画面出ればオッケーです。
駄目ならエラー見つつ頑張ってください。
routes.rbの設定
起動したので、routesを書いてURLを生成します。
適当でも良いですが、せっかくなので少し真面目に書きます。
resourcesをnewsにしているのは作ろうとしているアプリケーションのURLだからです。
Rails.application.routes.draw do
namespace :api do
namespace :v1 do
resources :news
end
end
end
routeの確認
railsの操作をする際は色んなことをやっていくことになるので、内部で操作していった方が楽だと思います。外からでも操作できるので、どっちでも良いです。
入ってやる方は以下のコマンドで入れます。
docker-compose exec rails bash
確認したらこんな感じで出ると思います。
rails初期から存在するrouteと共に設定したrouteが見れます。
これで上のrouteが正しく設定されたことを確認します。
root@69c223a51ae2:/app# rails routes
Prefix Verb URI Pattern Controller#Action
api_v1_news_index GET /api/v1/news(.:format) api/v1/news#index
POST /api/v1/news(.:format) api/v1/news#create
api_v1_news GET /api/v1/news/:id(.:format) api/v1/news#show
PATCH /api/v1/news/:id(.:format) api/v1/news#update
PUT /api/v1/news/:id(.:format) api/v1/news#update
DELETE /api/v1/news/:id(.:format) api/v1/news#destroy
rails_mandrill_inbound_emails POST /rails/action_mailbox/mandrill/inbound_emails(.:format) action_mailbox/ingresses/mandrill/inbound_emails#create
rails_postmark_inbound_emails POST /rails/action_mailbox/postmark/inbound_emails(.:format) action_mailbox/ingresses/postmark/inbound_emails#create
rails_relay_inbound_emails POST /rails/action_mailbox/relay/inbound_emails(.:format) action_mailbox/ingresses/relay/inbound_emails#create
rails_sendgrid_inbound_emails POST /rails/action_mailbox/sendgrid/inbound_emails(.:format) action_mailbox/ingresses/sendgrid/inbound_emails#create
rails_mailgun_inbound_emails POST /rails/action_mailbox/mailgun/inbound_emails/mime(.:format) action_mailbox/ingresses/mailgun/inbound_emails#create
rails_conductor_inbound_emails GET /rails/conductor/action_mailbox/inbound_emails(.:format) rails/conductor/action_mailbox/inbound_emails#index
POST /rails/conductor/action_mailbox/inbound_emails(.:format) rails/conductor/action_mailbox/inbound_emails#create
rails_conductor_inbound_email GET /rails/conductor/action_mailbox/inbound_emails/:id(.:format) rails/conductor/action_mailbox/inbound_emails#show
PATCH /rails/conductor/action_mailbox/inbound_emails/:id(.:format) rails/conductor/action_mailbox/inbound_emails#update
PUT /rails/conductor/action_mailbox/inbound_emails/:id(.:format) rails/conductor/action_mailbox/inbound_emails#update
DELETE /rails/conductor/action_mailbox/inbound_emails/:id(.:format) rails/conductor/action_mailbox/inbound_emails#destroy
rails_conductor_inbound_email_reroute POST /rails/conductor/action_mailbox/:inbound_email_id/reroute(.:format) rails/conductor/action_mailbox/reroutes#create
rails_service_blob GET /rails/active_storage/blobs/:signed_id/*filename(.:format) active_storage/blobs#show
rails_blob_representation GET /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations#show
rails_disk_service GET /rails/active_storage/disk/:encoded_key/*filename(.:format) active_storage/disk#show
update_rails_disk_service PUT /rails/active_storage/disk/:encoded_token(.:format) active_storage/disk#update
rails_direct_uploads POST /rails/active_storage/direct_uploads(.:format) active_storage/direct_uploads#create
controllerの作成
これもコマンドで作成します。
Controllerの名前はroutesで確認したControllerと同じにする必要があるので、その点だけ注意ください。
rails generate controller api/v1/news
作ったら中身です。
class Api::V1::NewsController < ApplicationController
def index
render json: { status: 'SUCCESS'}
end
end
とりあえずのレスポンスを返却するためだけの中身です。
途中でキャッシュ関連で変更が反映されないという問題に直面しましたが、その際はこちらを参考にして解決しました。
Rails6でも同様の方法で解決できるようです。
終わりに
Rails使うならここまではぱぱっと出来るようになりたいですね。
一通りやってみて環境構築周りの注意点とか分かったので、やっぱり手を動かして作るって大事です。