2020年7月21日火曜日

Sinatra で production や development としてデプロイする方法

概要

APP_ENV と configure を使うことでデプロイ時のモードを設定することができます
簡単な使い方とちょっと応用した使い方を紹介します

環境

  • macOS 10.15.6
  • Ruby 2.7.1p83
    • Sinatra 2.0.7

準備

  • bundle init
  • bundle config path vendor
  • vim Gemfile
gem "sinatra"
gem "sinatra-contrib"
  • bundle install

サンプルコード

とりあえず簡単なサンプルコードを紹介します

  • vim app.rb
require 'sinatra/base'

class App < Sinatra::Base
  configure :development do
    set :message, 'development'
  end

  configure :production do
    set :message, 'production'
  end

  get '/' do
    settings.message
  end
end
  • vim config.ru
require './app'
run App
  • bundle exec rackup config.ru
  • curl localhost:9292

=> development

  • APP_ENV=production bundle exec rackup config.ru
  • curl localhost:9292

=> production

という感じでモードを切り替えることができます
基本は configure 内で settings に対して値をセットすることでアプリ側で値を参照することができます

設定ファイルを使う

モードごとに設定ファイルを用意してそれを読み込む方法もあります
設定をアプリの外に出すことができるのでわかりやすくなります

  • vim production.yml
message: "production"
  • vim development.yml
message: "development"
  • vim app.rb
require 'sinatra/base'
require "sinatra/config_file"

class App < Sinatra::Base
  register Sinatra::ConfigFile

  def self.read_config(file)
    config_file file
  end

  configure :development do
    self.read_config('./development.yml')
  end

  configure :production do
    self.read_config('./production.yml')
  end

  get '/' do
    settings.message
  end
end

注意点としては configure 内部でコールするメソッドはクラスメソッドとして定義する必要があります
クラスメソッドで定義しないと NoMethodError: undefined method read_config for App:Class になります
helper などを使う場合もクラスメソッドとして定義しましょう

共通化したい場合は Base クラスを使う

コントローラを複数に分けることがある場合は Base となるコントローラを作成してそれを元にリソースごとなどでコントローラを作成しましょう

  • vim base.rb
require 'sinatra/base'
require "sinatra/config_file"

class Base < Sinatra::Base
  register Sinatra::ConfigFile

  def self.read_config(file)
    config_file file
  end

  configure :development do
    self.read_config('./development.yml')
  end

  configure :production do
    self.read_config('./production.yml')
  end
end
  • vim app.rb
require './base'

class App < Base
  get '/' do
    settings.message
  end
end

おまけ: 環境変数で上書きできるようにする

設定の話になりますが環境変数で設定を上書きしたい場合があると思います
今回の方式であれば一番単純なのは read_config で上書きする方法があります

  • vim base.rb
require 'sinatra/base'
require "sinatra/config_file"

class Base < Sinatra::Base
  register Sinatra::ConfigFile

  def self.read_config(file)
    config_file file
    set :message, ENV["MESSAGE"] if ENV["MESSAGE"]
  end

  configure :development do
    self.read_config('./development.yml')
  end

  configure :production do
    self.read_config('./production.yml')
  end
end
  • MESSAGE=hoge APP_ENV=production bundle exec rackup config.ru

ただこれだと設定ファイルに記載の項目ごとに read_config に上書きするための設定を記載しなければならなくなります
なので設定ファイルの YAML ファイルに環境変数を仕込んであげましょう

  • vim development.yml.erb
message: <%= ENV["MESSAGE"] || "development" %>
  • vim base.rb
require 'sinatra/base'
require "sinatra/config_file"

class Base < Sinatra::Base
  register Sinatra::ConfigFile

  def self.read_config(file)
    config_file file
  end

  configure :development do
    self.read_config('./development.yml.erb')
  end

  configure :production do
    self.read_config('./production.yml')
  end
end
  • MESSAGE=hoge bundle exec rackup config.ru
  • bundle exec rackup config.ru

たぶん erb を使う方法が一番キレイかなと思います

最後に

Sinatra で環境ごとに設定を切り分ける方法を紹介しました
APP_ENV と configure を使えば簡単でできることがわかりました
基本は初期設定を環境ごとに切り替える感じなるかなと思います
環境変数などを使って更に設定を上書きできるようにしてもいいかもしれません

参考サイト

0 件のコメント:

コメントを投稿