在 docker 中运行时,Flyway 无法识别迁移名称格式

Ant*_*ton 1 java flyway kotlin docker ktor

从 IDE 运行时迁移正常

输出:

INFO: Successfully applied 1 migration to schema `db`, now at version v1
Run Code Online (Sandbox Code Playgroud)

但是当我从容器运行应用程序时,输出:

example  | Exception in thread "main" 
example  | org.flywaydb.core.api.FlywayException: Invalid SQL filenames found:
example  | Unrecognised migration name format: V1__Example.sql
Run Code Online (Sandbox Code Playgroud)

我尝试过不同的Java版本。进入容器本身并查看迁移文件,看起来没问题。也许我可以从这里得到一些想法?

重现问题的示例代码:

应用程序.kt

package com.example
import com.mysql.cj.jdbc.MysqlDataSource
import com.typesafe.config.ConfigFactory
import io.ktor.server.application.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
import org.flywaydb.core.Flyway

fun main() {
    embeddedServer(Netty, port = 8080, host = "0.0.0.0", module = Application::module)
        .start(wait = true)
}

fun Application.module() {
    val conf = ConfigFactory.load()
    val mysqlDataSource = MysqlDataSource()
    mysqlDataSource.setURL(conf.getString("database.url"))

    Flyway.configure().dataSource(
        mysqlDataSource
    )
        .validateMigrationNaming(true)
        .load()
        .migrate()
}
Run Code Online (Sandbox Code Playgroud)

Dockerfile

FROM gradle:7-jdk11 AS build
COPY --chown=gradle:gradle . /home/gradle/src
WORKDIR /home/gradle/src
RUN gradle buildFatJar --no-daemon

FROM eclipse-temurin:11-jdk
EXPOSE 8080:8080
RUN mkdir /app
COPY --from=build /home/gradle/src/build/libs/*.jar /app/x.jar
ENTRYPOINT ["java","-jar","/app/x.jar"]
Run Code Online (Sandbox Code Playgroud)

docker-compose.yml

version: '3.5'
services:
  db:
    image: mysql:8.0
    container_name: db
    restart: always
    command: --default-authentication-plugin=caching_sha2_password
    environment:
      MYSQL_DATABASE: ${MYSQL_DB}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
    ports:
      - ${MYSQL_PORT}:${MYSQL_PORT}
    expose:
      - ${MYSQL_PORT}
    healthcheck:
      test: mysqladmin ping -h 127.0.0.1 -u $$MYSQL_USER --password=$$MYSQL_PASSWORD
      interval: 5s
      timeout: 5s
      retries: 55
  api:
    image:  example:test
    container_name: example
    ports:
      - '8080:8080'
    expose:
      - '8080'
    env_file: .env
    depends_on:
      db:
        condition: service_healthy
Run Code Online (Sandbox Code Playgroud)

依赖关系

dependencies {
    implementation("io.ktor:ktor-server-core-jvm")
    implementation("io.ktor:ktor-server-netty-jvm")
    implementation("org.flywaydb:flyway-core:9.20.0")
    implementation("org.flywaydb:flyway-mysql:9.20.0")
    implementation("mysql:mysql-connector-java:8.0.33")
}
Run Code Online (Sandbox Code Playgroud)

您可以在https://github.com/Skarpton/flyway-docker-problem中查看完整代码

更新:

看起来在 docker 中程序找不到任何 ResourceTypeProvider。这意味着没有配置前缀。

代码:

fun Application.module() {
    val conf = ConfigFactory.load()
    val mysqlDataSource = MysqlDataSource()
    mysqlDataSource.setURL(conf.getString("database.url"))

    val load = Flyway.configure().dataSource(
        mysqlDataSource
    )
        .validateMigrationNaming(true)
        .load()
    print(load.configuration.pluginRegister.getPlugins(ResourceTypeProvider::class.java)). //this is the interesting line
    load.migrate()

}
Run Code Online (Sandbox Code Playgroud)

ide 中的输出:

[org.flywaydb.core.internal.resource.CoreResourceTypeProvider@2381b1e8]

在泊坞窗中:

[]

Ant*_*ton 5

问题在于构建胖罐子。问题是必要的插件没有添加到 META-INF/services/org.flywaydb.core.extensibility.Plugin 文件中。我通过使用 Shadowjar 插件和配置 mergeServiceFiles() 修复了它。我将修复版本推送到原始存储库https://github.com/Skarpton/flyway-docker-problem