デプロイ後のマイグレーション

デプロイ後のマイグレーションは、デプロイ後に任意で実行できる通常のRailsマイグレーションです。デフォルトでは、これらのマイグレーションは他のマイグレーションと一緒に実行されます。これらのマイグレーションをスキップするには、rake db:migrateを実行するときに環境変数SKIP_POST_DEPLOYMENT_MIGRATIONS を空でない値に設定する必要があります。

例えば、これはデプロイ後のマイグレーションを含むすべてのマイグレーションを実行することになります:

bundle exec rake db:migrate

しかし、これはデプロイ後のマイグレーションをスキップします:

SKIP_POST_DEPLOYMENT_MIGRATIONS=true bundle exec rake db:migrate

GitLab.comでは、デプロイ後のマイグレーションパイプラインを通じて、リリースマネージャの判断でこれらのマイグレーションが毎日実行されます。

デプロイメントのインテグレーション

GitLabの新しいバージョンのデプロイにChefを使っていて、新しいバージョンのデプロイ後にデプロイ後のマイグレーションを実行したいとします。普段はchef-client というコマンドを使っているとします。この機能を使うには、次のようにコマンドを実行する必要があります:

SKIP_POST_DEPLOYMENT_MIGRATIONS=true sudo chef-client

すべてのサーバーの更新が完了したら、環境変数_なしで_1台のサーバーでchef-client

このプロセスは他のデプロイ手法でも同様です。まず環境変数を設定した状態でデプロイし、次に環境変数を_設定しない_状態で1台のサーバーを再デプロイします。

マイグレーションの作成

デプロイ後のマイグレーションを作成するには、以下のRailsジェネレータを使用できます:

bundle exec rails g post_deployment_migration migration_name_here

これはdb/post_migrate でマイグレーションファイルを生成します。これらのマイグレーションは、通常のRailsマイグレーションとまったく同じように動作します。

使用例

デプロイ後のマイグレーションは、既存のバージョンのGitLabが依存している状態を変更するマイグレーションに使用できます。例えば、テーブルからカラムを削除したいとします。この場合、GitLabインスタンスが実行中にこのカラムが存在することに依存するため、ダウンタイムが必要になります。通常、このような場合は以下の手順に従います:

  1. GitLabインスタンスを停止します。
  2. カラムを削除してマイグレーションを実行
  3. GitLabインスタンスを再度起動します。

デプロイ後のマイグレーションを使うことで、代わりに以下のステップを踏むことができます:

  1. デプロイ後のマイグレーションを無視して新しいバージョンのGitLabをデプロイします。
  2. rake db:migrate を再実行しますが、環境変数は設定しません。

ここでは、マイグレーションは新しいバージョン(カラムに依存しなくなった)がデプロイされた_後に_行われるので、ダウンタイムは必要ありません。

マイグレーションが役に立つ他の例をいくつか挙げます:

  • GitLabのバグによって生成されたデータのクリーンアップ
  • テーブルの削除
  • あるSidekiqキューから別のキューへのジョブのマイグレーション