flywayのセットアップに関してのメモ

プロジェクトのDB migrationにflywayを使うことにしました。
コマンドでの利用も考えましたが、
DBをDockerにしたかったのでDockerのコンテナにてflywayを使うことにしました
セットアップなどはDockerにてされますので設定だけをすればOKなはずでしたが…
少々問題に突き当たりましたので記事として残しておきたいと思います

flywayコマンドのPATHが通らないとエラーになる

特にDB接続設定を書くだけで特には意識はしていませんでした
しかし、実行するとこんなエラーでコンテナ実行が止まってしまいます

Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "flyway": executable file not found in $PATH: unknown

普通にPATHにflywayコマンドが存在しないと言うだけでしょうね
こんな初歩的なエラーが公式Dockerfileで起きることがあるのか?

対策

原因はあとに書くとして今回の原因はVolumeのマウントが原因でした

そもそもflywayでは/flyway以下にsql,conf,driversなどを指定します
それぞれの設定、SQLファイルなどをコマンド実行で処理されていきます

今回はこの/flywayのディレクトリ構造を./flywayに作成してmountさせました

    volumes:
      - ./flyway:/flyway

これだと今回のエラーになります
正しい書き方は必ずそれぞれ個別に指定しましょう

    volumes:
      - ./flyway/sql:/flyway/sql

詳細: https://github.com/flyway/flyway-docker?tab=readme-ov-file#supported-volumes

原因

原因は/flywayディレクトリ内にコマンドを展開する箇所に書き込みエラーとなっている…
はずです(エラーは特には出ません)

原因調査

本家のDockerfileはこちら : https://github.com/flyway/flyway-docker/blob/main/Dockerfile

はじめにPATHがどこを参照しているかを確認します

ENV PATH=”/flyway:${PATH}” ENTRYPOINT [“flyway”]

ここから/flyway/flywayコマンドを参照していることがわかります

このことからflywayコマンドの実行がないか、作成できないかが原因ということがわかります

/flywayをvolume mountするので、作成されるんじゃないのではないでしょうか?

コマンド作成されている箇所はこちらですね。
curlで最新のflywayコマンドを取得しているようですね…

WORKDIR /flyway RUN curl -L ${FLYWAY_ARTIFACT_URL}${FLYWAY_VERSION}/flyway-commandline-${FLYWAY_VERSION}.tar.gz -o flyway-commandline-${FLYWAY_VERSION}.tar.gz \ && gzip -d flyway-commandline-${FLYWAY_VERSION}.tar.gz \ && tar -xf flyway-commandline-${FLYWAY_VERSION}.tar –strip-components=1 \ && rm flyway-commandline-${FLYWAY_VERSION}.tar \ && chmod -R a+r /flyway \ && chmod a+x /flyway/flyway

はい、詳細は省きますが、/flyway/flyway コマンドの作成は試みています

ソースは問題ありません…

試しにVolumesを指定しないで実行すると問題なくflywayコマンドが実行されることも確認できます

なぜ、volumeでmountした/flywayの場合にはflywayコマンドが作成されないのか…

と、そこまでは調査必要がないと思いましたのでここまで

ま、自分で作るなら curlの結果は/tmpに格納してコマンドは/usr/local/binとかにするほうが良いですね

終いに

今回、エラーメッセージをWeb検索ですれば簡単に対策が分かるかなと思いました。
ですが、ネット上にはなかったので忘れないようにメモを残しておきました。
Dockerの公式掲示板にはありましたが解決はしていませんでした

メモ: 今回プロジェクトで作ったファイル

services:
  db:
    image: mariadb:10.11
    command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    healthcheck:
      test: mysqladmin ping -utest -ptest
    environment:
      MYSQL_ROOT_PASSWORD: "test"
      MYSQL_USER: "test"
      MYSQL_PASSWORD: "test"
      MYSQL_DATABASE: "app"
  flyway:
    image: flyway/flyway
    command: migrate
    volumes:
      - ./docker/flyway/conf:/flyway/conf
      - ./migration:/flyway/sql
    depends_on:
      db:
        condition: service_healthy