はじめに
こんにちは!
バックエンドエンジニアの matsuura です。
Gakken LEAP Advent Calendar 2024の18日目の記事をお届けいたします!
皆さんは、データベースマイグレーションやっていますか?
今回は、Flywayを使ったDocker環境でのマイグレーション実行や、環境差がある場合の対応に取り組んでみたので、その内容をご紹介していきます!
取り組んだ内容
【基本編】DockerでFlywayを実行する
こちらで紹介している内容は、どの環境でも同じクエリが実行されるパターンです。
環境ごとにクエリを実行させたい場合は、スキップしてこちらまで進んでもらえたらと思います。
ディレクトリ構成
Flywayのマイグレーションファイルを管理するため、次のようなディレクトリ構成を採用しました。
flyway/
├── sql
│ ├── V1_0__create-table.sql
│ ├── V1_1__insert-initial-data.sql
│ └── V2_0__insert-additional-data.sql
クエリ実行順について
Flywayでは、各クエリを以下のような命名にするように定められています。
V{バージョン名}__{説明}.sql
- バージョン名
-
_
を区切り文字として設定します。上記例では「1_0」や「1_1」としている部分がこれにあたります。 - 「1_0_2」のようにマイナーバージョンを追加することも可能です。
-
- 説明
- バージョンの後ろに
__
(アンダースコアを2つ)をつけた際、それ以降は「説明」という扱いになります。 - クエリの説明を記述しておきます。
- バージョンの後ろに
Flywayはバージョン順にクエリを実行してくれます。
上の場合、
V1_0 → V1_1 → V2_0
という順で実行されます。
バージョンが重複すると、マイグレーション実行時にエラーが発生します。
ネーミングに注意しましょう。
compose.yaml
以下は、FlywayをDocker Composeで実行するためのcompose.yamlファイルのサンプルです。
x-template: &flyway-template
image: flyway/flyway
volumes:
- ./flyway/sql:/flyway/sql
environment:
- FLYWAY_URL=<データベースのURL>
- FLYWAY_USER=root
- FLYWAY_PASSWORD=root
services:
flyway-migrate:
<<: *flyway-template
command: migrate
実行コマンド
次のコマンドを実行することで、マイグレーションが実施されます。
docker compose run --rm flyway-migrate
これで、./flyway/sql
下のクエリが対象のDBで実行されます。
マイグレーションの確認と取り消し
以下のようにcompose.yamlを変更しておくことで、マイグレーションの実行状況の確認や実行内容の取り消しを行うこともできます。
services:
flyway-migrate:
<<: *flyway-template
command: migrate
+ flyway-clean:
+ <<: *flyway-template
+ command: clean
+ flyway-info:
+ <<: *flyway-template
+ command: info
実行コマンドは以下の通りです。
# 実行状況の確認
docker compose run --rm flyway-info
# マイグレーションの取り消し
docker compose run --rm flyway-clean
【応用編】開発で環境差分がある場合の対応
ここまでで、FlywayをDockerコンテナで実行し、マイグレーションすることが可能になりました。
ただ、このままでは、開発環境や検証環境、本番環境など、どの環境においても、同一のクエリが実行されることになってしまいます。
たとえば、どの環境にも共通で同一構成テーブルを作成しますが、画像を取得するURLなどを格納するカラムには、環境ごとに異なる値を設定したくなると思います。
ここでは、そんな環境差異がある場合の対応を紹介していきます。
ディレクトリ構成(変更後)
以前の構成からcommonとdevelop、productionを追加しました。
flyway/
├── sql
│ ├── common
│ │ ├── V1_0__create-table.sql
│ │ ├── V1_1__insert-initial-data.sql
│ │ └── V2_0__insert-additional-data.sql
│ ├── develop
│ │ └── V1_2__insert-initial-data-dev.sql
│ └── production
│ └── V1_2__insert-initial-data-prod.sql
- common: 全ての環境で共通のクエリを格納
- develop: 開発環境に対してのみ実行させたいクエリを格納
- production: 本番環境に対してのみ実行させたいクエリを格納
クエリ実行順について(変更後)
こちらの場合でも、バージョンで指定した順にクエリが実行されます。
develop
においては、
V1_0(common) → V1_1 (common) → V1_2 (develop) → V2_0(common)
となります。
compose.yaml差分
次のようにcompose.yamlで設定するボリュームマウントを変更することで、環境に対応したクエリを読み込ませることが可能になります。
開発環境
flyway:
volumes:
- ./flyway/sql/common:/flyway/sql/common
- ./flyway/sql/develop:/flyway/sql/develop
本番環境
flyway:
volumes:
- ./flyway/sql/common:/flyway/sql/common
- ./flyway/sql/production:/flyway/sql/production
これで、環境ごとに実行したいクエリをそれぞれ実行することが可能になります!
最後に
今回紹介したように、Flywayを活用することで、環境ごとに適したデータベースの状態を管理できるようになります。
ぜひ、参考にしてもらえたらと思います!
エンジニア募集
Gakken LEAP では教育をアップデートしていきたいエンジニアを絶賛大募集しています!!
ぜひお気軽にカジュアル面談へお越しください!!