LoginSignup
0
0

More than 1 year has passed since last update.

Railsの「開発」環境へのデプロイ

Posted at

想定した環境

タイトルの「開発」環境と言っている部分の想定は、

  • 何らかのCI/CD環境を用いRailsアプリをクラウドなりオンプレの実環境へデプロイをする
  • 一般的な「開発/dev/development」→「ステージング/stg/staging」→「運用/prd/prod/production」といった環境の流れを想定
  • この「開発」用途の環境であり、デプロイするたびにデータベース丸ごと壊し初期化して良い、というかしたい
  • RAILS_ENVdevelopment/productionとは別の話、「開発」環境だけどRAILS_ENV=productionである
  • そして初期化されたクリーンな状態で動作テストをしていく
  • 「運用」用途でデータベースの内容を維持していくものは対象にしてはいない

データベースを破壊すのに困ること

まず初期化だがrailsのコマンドで行おうとするとrails db:resetになると思う。そして、これを阻む諸々がある。

データベース破壊保護

そもそもRAILS_ENV=productionの場合、Rails5以降では、データベース破壊系コマンドに対する保護が入っているので、DISABLE_DATABASE_ENVIRONMENT_CHECK=1を設定する必要がある。

Spring preloader

また、Rails4.1以降プリローダーとしてSpringが入り、これがrailsコマンドの実行を阻むので、DISABLE_SPRING=1を指定する必要がある。

PostgreSQL 13

ここは、PostgreSQL限定の話になるが、該当データベースに対してコネクションが貼られた状態の場合、単純にはDROP DATABASEできない仕様に変わっており(12→13)、特にCI/CDの様な形でアプリケーションプロセスが動いている状態ではdropできなくなっている。ここでPostgreSQL側はWITH (FORCE)という強制実行のオプションを付与しdropできる様になっているが、rails側が生成するクエリーにはそのオプションが付与されないのでdb:resetの実行では基本的に初期化できない(アプリケーションのデプロイによる再起動やタイムアウトでコネクションが切れていた場合に稀に成功するので悩む)。

上記の記事の様にモンキーパッチを当てて対処するのもあるかもしれませんが、メンテナンスの事を考えてCI/CD側のステップで行うというのが良いと思う。

結果

実際のCI/CD実装によるかと思うのですが、次のようなCLIコマンド/環境変数を実行する感じになる(あくまでもシェルスクリプト的なイメージ例)

# PostgreSQLの場合データベース初期化
PGPASSWORD={何らかの機密情報ストアー系から取得し環境変数で指定} \
psql -h ${POSTGRES_HOST} -U ${POSTGRES_USER} template1 \
  -c 'DROP DATABASE IF EXISTS \"${POSTGRES_DB}\" WITH (FORCE)'

# Rails側での初期化処理
RAILS_ENV=production \
RAILS_MASTER_KEY={何らかの機密情報ストアー系から取得し環境変数で指定} \
DISABLE_DATABASE_ENVIRONMENT_CHECK=1 \
DISABLE_SPRING=1 \
bundle exec rails db:reset

もしかしたら、使っているライブラリーや環境によっては他の環境変数などの設定が必要かも。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0