Menjalankan Flyway dengan Docker

Pada artikel sebelumnya kita sudah bahas tentang penggunaan Liquibase secara standalone, yaitu tidak di-embed dalam project/aplikasi yang kita buat. Di artikel ini, kita akan buat versi yang serupa, tapi menggunakan Flyway.

Kenapa menggunakan Flyway?

Ya sebenarnya karena itulah yang kita gunakan saat ini di ArtiVisi. Untuk memudahkan team member, sehingga bisa lanjut menggunakan model konfigurasi dan struktur folder yang sudah biasa dipakai. Selain itu juga untuk membandingkan dengan Liquibase, lebih nyaman mana untuk digunakan.

Struktur Folder

Berikut adalah struktur folder yang kita gunakan.

Struktur Folder

Semua hal yang berkaitan dengan konfigurasi dan migrasi kita masukkan ke folder flyway. Di top level hanya ada compose.yml saja. Isi compose.yml sama dengan di artikel Liquibase kemarin, yaitu seperti ini

services:
  db-belajar:
    image: mysql:8
    platform: linux/x86_64
    environment:
      - MYSQL_RANDOM_ROOT_PASSWORD=yes
      - MYSQL_DATABASE=belajardb
      - MYSQL_USER=belajar
      - MYSQL_PASSWORD=belajar123
    ports:
      - 33061:3306
    volumes:
      - ./db-belajar:/var/lib/mysql

Script Migrasi

Script migrasi juga dibuat dengan SQL. Flyway memiliki dua jenis file migrasi, yaitu:

  • Versioned
  • Repeatable

Kita hanya menggunakan yang Versioned saja. Aturan penamaannya adalah:

  • diawali dengan huruf V
  • diikuti dengan nomor versi, yang akan diurutkan sesuai urutan alfanumerik
  • dilanjutkan dengan dua underscore seperti ini : __
  • diikuti dengan nama/deskripsi. Pemisah antar kata boleh pakai spasi atau pakai underscore
  • diakhiri dengan extension .sql

Berikut contoh file migrasinya, kita beri nama V2024110701__Skema_Awal.sql

create table customer (
    id varchar(36),
    customer_name varchar(200) not null,
    email varchar(100) not null,
    mobile_phone varchar(50) not null,
    primary key (id)
);

create table merchant (
    id varchar(36),
    merchant_name varchar(20) not null,
    primary key (id)
);

Isi file adalah SQL biasa, yang bisa kita tes dulu langsung ke databasenya. Tidak ada komentar/metadata khusus seperti pada Liquibase.

Konfigurasi

Konfigurasi Flyway kita buat dalam format toml sebagai berikut

[flyway]
locations = ["filesystem:migrations"]

[environments.default]
url = "jdbc:mysql://localhost:33061/belajardb?useSSL=false&allowPublicKeyRetrieval=true"
user = "belajar"
password = "belajar123"

Ada dua blok di sana : flyway dan environment. Blok flyway isinya adalah konfigurasi global, sedangkan blok environment berisi konfigurasi yang spesifik pada environment tertentu. Misalnya kita ingin membedakan konfigurasi development, staging, dan production.

Di blok flyway kita menyebutkan nama folder yang berisi script migrasi di variable locations. Sebetulnya konfigurasi locations ini opsional. Kita bisa taruh script migrasi di folder sql dan Flyway akan mendeteksi secara otomatis. Akan tetapi, pada waktu dijalankan ada warning bahwa deteksi otomatis ini akan dihilangkan di versi selanjutnya. Jadi ya sudah kita pasang saja konfigurasinya.

Driver Database

Driver database harus kita unduh sendiri, kemudian diletakkan di folder drivers. Cara mengunduhnya bebas saja. Saya menggunakan perintah wget di terminal sebagai berikut:

wget -c -P flyway/drivers "https://repo1.maven.org/maven2/com/mysql/mysql-connector-j/8.0.33/mysql-connector-j-8.0.33.jar"

Menjalankan Database

Database kita jalankan dengan perintah docker compose up. Langkah-langkahnya sama dengan artikel sebelumnya, jadi tidak saya ulangi lagi di sini.

Menjalankan Migrasi Database

Kita jalankan migrasi menggunakan Docker, supaya tidak perlu menginstal aplikasi Flyway di PC/Laptop/Server

docker run --rm --network=host -v ${PWD}/flyway:/flyway/project flyway/flyway migrate -workingDirectory="project"

Outputnya seperti ini

A more recent version of Flyway is available. Find out more about Flyway 10.21.0 at https://rd.gt/3rXiSlV

Flyway OSS Edition 10.20.1 by Redgate

See release notes here: https://rd.gt/416ObMi
Database: jdbc:mysql://localhost:33061/belajardb?useSSL=false&allowPublicKeyRetrieval=true (MySQL 8.4)
WARNING: Flyway upgrade recommended: MySQL 8.4 is newer than this version of Flyway and support has not been tested. The latest supported version of MySQL is 8.1.
Schema history table `belajardb`.`flyway_schema_history` does not exist yet
Successfully validated 2 migrations (execution time 00:00.019s)
Creating Schema History table `belajardb`.`flyway_schema_history` ...
Current version of schema `belajardb`: << Empty Schema >>
Migrating schema `belajardb` to version "2024110701 - Skema Awal"
Migrating schema `belajardb` to version "2024110702 - Rename Phone Column"
Successfully applied 2 migrations to schema `belajardb`, now at version v2024110702 (execution time 00:00.029s)

Mengecek Hasil Migrasi

Login ke database dengan perintah berikut

docker exec -it flyway-docker-db-belajar-1 mysql -u belajar belajardb -p

Kita cek isi databasenya, seharusnya tabel-tabel sudah terbentuk

mysql> show tables;
+-----------------------+
| Tables_in_belajardb   |
+-----------------------+
| customer              |
| flyway_schema_history |
| merchant              |
+-----------------------+
3 rows in set (0.01 sec)

Kemudian kita cek isi tabel flyway_schema_history

mysql> select * from flyway_schema_history\G
*************************** 1. row ***************************
installed_rank: 1
       version: 2024110701
   description: Skema Awal
          type: SQL
        script: V2024110701__Skema_Awal.sql
      checksum: -1690424458
  installed_by: belajar
  installed_on: 2024-11-08 09:07:49
execution_time: 20
       success: 1
*************************** 2. row ***************************
installed_rank: 2
       version: 2024110702
   description: Rename Phone Column
          type: SQL
        script: V2024110702__Rename_Phone_Column.sql
      checksum: 877302682
  installed_by: belajar
  installed_on: 2024-11-08 09:07:49
execution_time: 9
       success: 1
2 rows in set (0.01 sec)

Flyway sudah berhasil dijalankan secara standalone tanpa dibundel ke dalam aplikasi. Bila ingin mencoba, source code bisa didapatkan di repo Github.

Semoga bermanfaat.