DockerとFlywayで簡単にデータベースをマイグレーションする方法

スポンサーリンク
DockerとFlywayで簡単にデータベースをマイグレーションする方法 ノウハウ
DockerとFlywayで簡単にデータベースをマイグレーションする方法
この記事は約18分で読めます。
よっしー
よっしー

こんにちは。よっしーです(^^)

今日は、flywayを使用したデータベース環境の構築についてご紹介します。先日、M1 Mac 上の docker で MySQL 環境を構築しましたので、その環境をベースにflywayの環境を構築していきます。

スポンサーリンク

実行環境

この記事で使用されているコマンドは下記の環境で実行されています。

% sw_vers 
ProductName:            macOS
ProductVersion:         13.2.1
BuildVersion:           22D68

% sysctl machdep.cpu.brand_string
machdep.cpu.brand_string: Apple M1 Max

% docker --version
Docker version 20.10.23, build 7155243

使用している docker desktop のバージョンは下図になります。

docker desktop のバージョン
docker desktop のバージョン

docker を使用した flyway環境の構築

下記のDocker関連のファイルを使用しています。

ディレクトリ構造

各種ファイルの配置は下記のようになっています。

db
├── .env
├── .tool-versions
├── docker-compose.yml
├── flyway
│   ├── Dockerfile
│   ├── conf
│   │   └── flyway.conf
│   └── sql
│       ├── V1.0.1__create_sample_table.sql
│       └── V1.0.2__insert_sample_data.sql
└── mysql
    ├── Dockerfile
    └── my.cnf

.env

MySQLの環境変数が記載されているファイルになります。

MYSQL_DATABASE=sample
MYSQL_ROOT_PASSWORD=P@ssw0rd
TZ=Asia/Tokyo

.tool-versions

mysqlクライアントのバージョンを記載しています。

mysql 5.7.31

docker-compose.yml

version: '3'

x-template: &flyway-cmd
  build: ./flyway
  volumes:
    - ./flyway/sql:/flyway/sql
    - ./flyway/conf:/flyway/conf
  depends_on:
    - mysql
  profiles:
    - flyway
  networks:
    - net

services:

  mysql:
    build: ./mysql
    container_name: mysql
    platform: linux/x86_64
    ports:
      - 127.0.0.1:3306:3306
    environment:
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      TZ: ${TZ}
    volumes:
      - ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf
    networks:
      - net

  flyway-baseline:
    <<: *flyway-cmd
    command: baseline

  flyway-migrate:
    <<: *flyway-cmd
    command: migrate

  flyway-info:
    <<: *flyway-cmd
    command: info

networks:
  net:

x-templates

Docker Composeのx-templatesは、Composeファイルで使用することができる、再利用可能なテンプレートを定義するための機能です。

x-templatesは、YAMLファイル内に定義された、Composeファイルに含まれる再利用可能なテンプレートの定義を示すマーカーです。これにより、Composeファイル内でテンプレートを定義し、必要な場所で参照することができます。

今回は、x-templatesを使用して、flywayサービスのテンプレートを定義しています。定義されたテンプレートは、&flyway-cmdマーカーで開始され、その下にflywayサービスの定義が含まれます。サービスの定義では、<<演算子を使用して、定義されたテンプレートを参照しています。これにより、同じテンプレートを複数の場所で再利用できるようになります。

x-templatesを使用することで、Composeファイル内で定義された複数のサービスで、共通の設定やリソースを簡単に再利用することができます。また、テンプレートを使用することで、Composeファイル内の冗長性を減らし、よりシンプルで読みやすい構成ファイルを作成することができます。

networks

Docker Composeのnetworksは、Composeファイルで定義された複数のサービス間での通信を可能にするための機能です。

Composeファイルにnetworksを定義することで、Composeが自動的にDockerネットワークを作成し、サービスをそのネットワークに接続します。これにより、複数のサービスが同じネットワークに接続され、互いに通信できるようになります。

今回は、netいう名前のネットワークを定義しています。そして、mysqlとflyway-cmdのサービスがこのネットワークに接続されています。

各サービスのnetworksセクションでは、ネットワークの名前を指定することで、サービスをネットワークに接続することができます。ここでは、mysqlとflyway-cmdサービスがnetに接続されているため、この2つのサービスは互いに通信することができます。

networksを使用することで、複数のサービスが同じネットワークに接続され、互いに通信することができるようになります。また、ネットワークの定義により、サービスが異なるネットワークに接続されることもできます。この場合、接続されたネットワーク間での通信は不可能になります。

flyway/Dockerfile

FROM flyway/flyway:7.15.0

flywayの最新のイメージで起動させると、MySQL 5.7はサポート対象外となり、エラーとなってしまうため、MySQL 5.7がサポート対象になっている最新のバージョンであろうflyway:7.15.0を使用しています。

% docker compose run --rm flyway-info
[+] Running 1/0
⠿ Container mysql Running 0.0s
Flyway Community Edition 9.16.1 by Redgate
See release notes here: https://rd.gt/416ObMi

Database: jdbc:mysql://mysql/sample (MySQL 5.7)
ERROR: Flyway Teams Edition or MySQL upgrade required: MySQL 5.7 is no longer supported by Flyway Community Edition, but still supported by Flyway Teams Edition.

flywa/conf/flyway.conf

 flyway.url=jdbc:mysql://mysql/sample
flyway.user=root
flyway.password=P@ssw0rd

flyway/sql/V1.0.1__create_sample_table.sql

create table sample (
      id   INT         AUTO_INCREMENT NOT NULL
    , name VARCHAR(30) NOT NULL
    , ts   TIMESTAMP   DEFAULT CURRENT_TIMESTAMP
    , dt   DATETIME    DEFAULT CURRENT_TIMESTAMP
    , PRIMARY KEY (id)
)
;

flyway/sql/V1.0.2__insert_sample_data.sql

insert into sample(name) values
  ("test")
  , ("テスト2")
  , ("てすと3")
;

mysql/Dockerfile

FROM mysql:5.7

mysql/my.cnf

[client]
default-character-set=utf8

[mysql]
default-character-set=utf8

[mysqldump]
default-character-set=utf8

[mysqld]
character-set-server=utf8

上記の設定は、MySQLクライアント、MySQLサーバー、およびmysqldumpツールの文字セットをUTF-8に設定するための設定です。UTF-8は、Unicodeの一種で、世界中のほとんどの言語に対応しているため、多言語のデータを扱う場合に一般的に使用される文字セットの1つです。

設定内容の解説は以下の通りです。

  • [client]:MySQLクライアントの設定を指定するセクションです。default-character-set=utf8は、MySQLクライアントがUTF-8の文字セットを使用するように設定するためのものです。
  • [mysql]:MySQLコマンドラインクライアントの設定を指定するセクションです。default-character-set=utf8は、MySQLコマンドラインクライアントがUTF-8の文字セットを使用するように設定するためのものです。
  • [mysqldump]:mysqldumpツールの設定を指定するセクションです。default-character-set=utf8は、mysqldumpがUTF-8の文字セットを使用するように設定するためのものです。
  • [mysqld]:MySQLサーバーの設定を指定するセクションです。character-set-server=utf8は、MySQLサーバーがUTF-8の文字セットを使用するように設定するためのものです。

これらの設定により、MySQLのクライアント、サーバー、およびmysqldumpツールがUTF-8の文字セットを使用するようになります。これにより、多言語のデータを扱う場合に文字化けが発生するのを防止することができます。

ビルド&起動

cd db
docker compose build
docker compose up -d

動作確認

ターミナルで flywayコマンドを実行して、テーブルの作成とデータの登録ができていれば完成です。

flyway info

% docker compose run --rm flyway-info
[+] Running 1/0
 ⠿ Container mysql  Running                                                                                                                  0.0s
Flyway Teams Edition 7.15.0 by Redgate
Database: jdbc:mysql://mysql/sample (MySQL 5.7)
----------------------------------------
Flyway Teams features are enabled by default for the next 27 days. Learn more at https://rd.gt/3A4IWym
----------------------------------------
Schema version: << Empty Schema >>

+-----------+---------+---------------------+------+--------------+---------+----------+
| Category  | Version | Description         | Type | Installed On | State   | Undoable |
+-----------+---------+---------------------+------+--------------+---------+----------+
| Versioned | 1.0.1   | create sample table | SQL  |              | Pending | No       |
| Versioned | 1.0.2   | insert sample data  | SQL  |              | Pending | No       |
+-----------+---------+---------------------+------+--------------+---------+----------+

Flyway infoコマンドは、Flywayで管理されているデータベースのマイグレーション情報を表示するためのコマンドです。

Flyway infoコマンドを実行すると、現在のデータベースのスキーマの状態を表示します。具体的には、Flywayが適用可能なマイグレーションの数、適用されたマイグレーションの数、未適用のマイグレーションの数、そして、各マイグレーションのステータス(適用済み、未適用、スキップ)が表示されます。

flyway baseline

% docker compose run --rm flyway-baseline
[+] Running 1/0
 ⠿ Container mysql  Running                                                                                                                  0.0s
Flyway Teams Edition 7.15.0 by Redgate
Database: jdbc:mysql://mysql/sample (MySQL 5.7)
----------------------------------------
Flyway Teams features are enabled by default for the next 27 days. Learn more at https://rd.gt/3A4IWym
----------------------------------------
Creating Schema History table `sample`.`flyway_schema_history` with baseline ...
Successfully baselined schema with version: 1

Flyway baselineは、Flywayを使用してデータベースをバージョン管理する際に、既存のスキーマやデータを初期状態としてマークするための機能です。

通常、Flywayは、データベースを初期状態から新しい状態に更新するために使用されます。しかし、既存のデータベースがある場合、Flywayが初期状態としてデータベースを認識しないため、新しいスキーマのバージョンを適用すると、既存のスキーマやデータが消去されてしまう可能性があります。

そこで、Flyway baselineを使用することで、既存のスキーマやデータを初期状態として認識させることができます。baselineコマンドを実行することで、Flywayは既存のスキーマやデータを基準線としてマークし、その後のマイグレーションでは、この基準線からバージョン管理を行うことができます。

例えば、既存のデータベースには、すでにテーブルやデータが存在している場合、baselineコマンドを実行することで、現在のデータベースの状態を初期状態としてマークすることができます。その後、Flywayのマイグレーションを適用することで、その初期状態からバージョン管理を行うことができます。

flyway migrate

% docker compose run --rm flyway-migrate 
[+] Running 1/0
 ⠿ Container mysql  Running                                                                                                                  0.0s
Flyway Teams Edition 7.15.0 by Redgate
Database: jdbc:mysql://mysql/sample (MySQL 5.7)
----------------------------------------
Flyway Teams features are enabled by default for the next 27 days. Learn more at https://rd.gt/3A4IWym
----------------------------------------
Successfully validated 3 migrations (execution time 00:00.085s)
Current version of schema `sample`: 1
Migrating schema `sample` to version "1.0.1 - create sample table"
Migrating schema `sample` to version "1.0.2 - insert sample data"
Successfully applied 2 migrations to schema `sample`, now at version v1.0.2 (execution time 00:00.246s)

Flyway migrateは、Flywayを使用してデータベースのスキーマをマイグレーションするためのコマンドです。

Flyway migrateを実行すると、Flywayが指定されたディレクトリからSQLスクリプトを読み込み、データベースのスキーマを更新します。具体的には、Flywayは、バージョン番号を持つSQLスクリプトを実行し、データベースのスキーマをそのバージョンに更新します。Flywayは、適用された各スクリプトに対して、適用されたバージョン番号を管理するためのメタデータテーブルを更新します。

このコマンドを実行すると、Flywayは指定されたディレクトリからSQLスクリプトを読み込み、適用されていないすべてのスクリプトを順番に実行します。また、実行された各スクリプトの情報をメタデータテーブルに追加して、次回のマイグレーションのためにスクリプトの適用状態を管理します。

Flyway migrateは、データベースのスキーマを更新するための基本的なコマンドです。このコマンドを使用して、アプリケーションの開発やリリースの際に、データベースのスキーマを最新の状態に保つことができます。

登録データ確認

% mysql -u root -p"P@ssw0rd" -h localhost -P 3306 -D sample --protocol=tcp -e "select * from sample;"
mysql: [Warning] Using a password on the command line interface can be insecure.
+----+--------------+---------------------+---------------------+
| id | name         | ts                  | dt                  |
+----+--------------+---------------------+---------------------+
|  1 | test         | 2023-04-02 16:39:42 | 2023-04-02 16:39:42 |
|  2 | テスト2      | 2023-04-02 16:39:42 | 2023-04-02 16:39:42 |
|  3 | てすと3     | 2023-04-02 16:39:42 | 2023-04-02 16:39:42 |
+----+--------------+---------------------+---------------------+

flywayとは

Flywayは、Javaで開発されたオープンソースのデータベース移行ツールです。Flywayを使用すると、データベースのスキーマやデータを安全かつ簡単にバージョン管理することができます。

Flywayの主な特徴は次のとおりです。

  • 軽量で単純な設計:Flywayは、わずかな依存関係を持つシンプルなツールです。
  • データベースのバージョン管理:Flywayを使用すると、データベースのバージョン管理を行うことができます。
  • 自動適用:Flywayは、自動的に変更を検出し、適用することができます。
  • 簡単なマイグレーションの作成:Flywayを使用すると、Java、SQL、Groovyなどのスクリプトを使用して簡単にマイグレーションを作成することができます。

Flywayは、Java、Scala、Groovy、KotlinなどのJVMベースの言語で使用できます。また、PostgreSQL、MySQL、Oracle、SQL Serverなどの主要なデータベースをサポートしています。Flywayは、簡単な構成で利用可能であるため、多くのプロジェクトで使用されています。

公式サイトは下記になります。

おわりに

今日は、flywayを使用したテーブルの作成やデータの登録をしてみました。次回は、CodeIgniter上で、データベース接続をしてみたいと思います。

よっしー
よっしー

また明日お会いしましょう!

コメント

タイトルとURLをコピーしました