Flyway + PostgreSQLのDBマイグレーション環境をDockerを使って構築する

# 概要
Dockerを使ってDBマイグレーション環境をローカル環境に構築する方法を紹介します。

Flywayでのマイグレーションと言えばgradleやsbtなどのプラグインを使うのが一般的？かと思いますが、Command-Lineで実行するやり方もあります。
https://flywaydb.org/getstarted/

そして、ツールが内包された公式のDockerImageがあったのでこれを使ってローカルでマイグレーション環境を構築してみます。
https://hub.docker.com/r/boxfuse/flyway/

# やりたいこと
- DockerコンテナでPostgreSQLを立ち上げる
- FlywayのDockerコンテナからPostgreSQLに対してマイグレーションを実行する

# 1. 必要なファイルを作成
## docker-composeの定義
複数の関連するDockerコンテナを管理する場合はdocker-composeでやるのが便利なので、yamlを書いていきます。

```docker-compose.yml
version: '3.4'

x-template: &flyway-template
  image: boxfuse/flyway:latest
  volumes:
    - ./sql:/flyway/sql # マイグレーション用SQLファイルの格納先
    - ./conf:/flyway/conf # 設定ファイルの格納先
  depends_on:
    - db

services:
  flyway-clean:
    <<: *flyway-template
    command: clean

  flyway-migrate:
    <<: *flyway-template
    command: migrate

  flyway-info:
    <<: *flyway-template
    command: info

  db:
    image: postgres:latest
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=pass
    ports:
      - 5432:5432
    volumes:
      - ./init:/docker-entrypoint-initdb.d # Create DataBase するinit用のSQLの格納先
    container_name: db
```

## flyway.conf ファイル定義

docker-composeで定義したDBの接続先情報などを指定します。
https://flywaydb.org/documentation/configfiles

```flyway.conf
flyway.url=jdbc:postgresql://db:5432/test_db
flyway.user=user
flyway.password=pass
```

※Composeはアプリケーションに対してネットワークを１つ設定します。
各コンテナ上のサービスはデフォルト・ネットワークに参加したら、同一ネットワーク上の他のコンテナから接続できるようになるため、コンテナ名`db`でPostgreSQLにアクセス可能になります。

# 初期化用SQLファイルを作成
マイグレーション対象のテーブルを作成するSQL

```create_database.sql
CREATE DATABASE test_db;
```

## マイグレーション用SQLファイルを作成
ひとまず適当に２つ用意

```V0.001__create_table.sql
CREATE TABLE IF NOT EXISTS test_table(test_id int, test_name varchar(255));
```

```V0.002__insert_table.sql
INSERT INTO test_table(test_id, test_name) VALUES (1, 'test');
```

## ディレクトリ構成
今まで作成したファイルは最終的にこんな感じの構成で配置する。

```
flyway-migration
├── docker-compose.yml
├── conf
│   └── flyway.conf
├── init
│   └── create_database.sql
└── sql
    ├── V0.001__create_table.sql
    └── V0.002__insert_table.sql
```

# 2.PostgreSQLコンテナ立ち上げ
コンテナを立ち上げる

```
$ docker-compose up -d db
```

`db`という名前で立ち上がっていることを確認

```
$ docker ps

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
52cbb658ae0a        postgres:latest     "docker-entrypoint.s…"   46 hours ago        Up 46 hours         0.0.0.0:5432->5432/tcp   db
```

# 3.flyway マイグレーション実行
`migrate` 実行
用意したマイグレーション用SQLが順に実行される

```
$ docker-compose run --rm flyway-migrate

Starting db ... done
Flyway Community Edition 5.1.4 by Boxfuse

Database: jdbc:postgresql://db:5432/test_db (PostgreSQL 10.5)
Successfully validated 2 migrations (execution time 00:00.040s)
Current version of schema "public": 0.002
Schema "public" is up to date. No migration necessary.
```

`info` 実行
マイグレーションの実行履歴が確認できる

```
$ docker-compose run --rm flyway-info

Starting db ... done
Flyway Community Edition 5.1.4 by Boxfuse

Database: jdbc:postgresql://db:5432/test_db (PostgreSQL 10.5)
Schema version: 0.002

+-----------+---------+--------------+------+---------------------+---------+
| Category  | Version | Description  | Type | Installed On        | State   |
+-----------+---------+--------------+------+---------------------+---------+
| Versioned | 0.001   | create table | SQL  | 2018-10-01 17:05:42 | Success |
| Versioned | 0.002   | insert table | SQL  | 2018-10-01 17:05:42 | Success |
+-----------+---------+--------------+------+---------------------+---------+
```

ちゃんとテーブルができていることを確認する。

```
$ pgcli -h localhost -U user  -p 5432

user@localhost:user> \connect test_db
You are now connected to database "test_db" as user "user"
Time: 0.018s

user@localhost:test_db> select * from test_table;
+-----------+-------------+
| test_id   | test_name   |
|-----------+-------------|
| 1         | test        |
+-----------+-------------+
```

できてますね！


`clean` 実行
マイグレーションによって作成されたテーブル等を削除したい場合はcleanを実行する

```
$ docker-compose run --rm flyway-clean
Starting db ... done
Flyway Community Edition 5.1.4 by Boxfuse

Database: jdbc:postgresql://db:5432/test_db (PostgreSQL 10.5)
Successfully cleaned schema "public" (execution time 00:00.042s)
```

# ソースコード
ソースコードは↓に公開してますのでよければ。
https://github.com/supimen/flyway-docker-migration

以上です。