0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

個人的備忘録:「migrate_app && server」は危険?Docker起動のベストプラクティスを考察してみた

Posted at

はじめに

この問題について考えたきっかけは、Golang を用いたマイクロサービスの開発中に、コンテナが再起動するたびにマイグレーションが実行され、意図しないデータの変更やアプリケーションの起動遅延が発生したことでした。

特に、破壊的変更を含むマイグレーションが誤って適用されるリスクがあることが問題となりました。

現在の Dockerfile の問題点

以下の Dockerfile では、コンテナ起動時に必ず migrate_app が実行される設定になっています。

CMD ["/bin/sh", "-c", "/app/migrate_app && /app/server"]

この設定では、アプリケーションが起動するたびにマイグレーションが実行されるため、以下の問題が発生する可能性があります。

問題点

  1. すでに適用済みのマイグレーションが再適用される
    migrate_app が idempotent(冪等性を持つ、つまり何度実行しても影響がない)でない場合、データベースの整合性が崩れる可能性があります。

    • 例えば、CREATE TABLE を含むマイグレーションを毎回実行すると、テーブルの重複エラーが発生します。
  2. アプリケーションの起動が遅くなる

    • 毎回マイグレーションを適用することで、不要な処理が発生し、アプリケーションの起動時間が長くなります。
  3. マイグレーション中にエラーが発生し、アプリケーションが起動しない

    • migrate_app が失敗すると server が起動しないため、コンテナが正しく動作しなくなるリスクがあります。
  4. 破壊的変更のリスク

    • スキーマ変更がある場合、既存データが失われる可能性があります。
    • DROP COLUMNALTER TABLE でカラムの変更があると、古いバージョンのアプリが動作しなくなることがあります。
    • データ移行が適切に行われないと、アプリケーションの互換性が損なわれる恐れがあります。

方法: マイグレーションを手動で適用する

アプリケーションのデプロイ前に手動でマイグレーションを適用し、コンテナ起動時には server だけを実行する方法です。

変更後の Dockerfile

CMD ["/app/server"]

この場合、デプロイのフローにマイグレーション処理を組み込み、データベースの更新が必要な場合のみ実行します。

まとめ

  • migrate_app を idempotent にするのが最も簡単な解決策。
  • マイグレーションを手動適用する場合、コンテナ起動時には server だけを実行する。
  • エントリポイントスクリプトを使うことで、マイグレーションの実行可否を制御できる。
  • 破壊的変更がある場合、適用前にバックアップを取り、段階的なリリースを検討する。

アプリケーションの要件に応じて、適切な方法を選択することが大事だと思いました!

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?