mavenでflywayのjarを作成してdocker-maven-pluginでdocker build(migrate)する

だいぶはまったのでまとめる。

### 使用するdocker-maven-plugin
docker-maven-pluginは以下の２つからリリースされている。

+ [fabric8io/docker-maven-plugin](https://github.com/fabric8io/docker-maven-plugin)
+ [spotify/docker-maven-plugin](https://github.com/spotify/docker-maven-plugin)

今回はfabric8ioのdocker-maven-pluginを使用した。



### docker buidするには

buidには２つのモードがある。

1. pom.xmlにfromやcmdを記述し、buid方法
2. pom.xmlから別のDockerfileを参照し、buidする方法


1に関しては以下の通り。

```xml
<configuration>
  <images>
    <image>
      <alias>service</alias> 
      <name>fabric8/docker-demo:${project.version}</name>

      <build> 
         <from>java:8</from> 
         <assembly>
           <descriptor>docker-assembly.xml</descriptor> 
         </assembly>
         <cmd> 
            <shell>java -jar /maven/service.jar</shell>
         </cmd>
      </build>
    </image>
</configuration>
```

２は以下のようになる。

```xml
        <configuration>
          <images>
            <image>
              <name>${project.name}</name>
              <build>
                <dockerFileDir>${project.basedir}</dockerFileDir>
              </build>
            </image>
          </images>
        </configuration>
```

2のやり方を選定した。
理由としては、

+ migrateの際に、sqlファイルがないといけないが、1のやり方だとCOPYができないから。

project直下にDockerfileを作成し、buid参照先を指定する。

```
project/
  ┝src
  ┝Dockerfile
  ┝pom.xml
```

### Dockerfileを使ってmigrateを行うには

```dockerfile:Dockerfile
FROM amazoncorretto:11-alpine
COPY maven /maven/jar/
COPY ${flyway.sqldir}/V1__Initialize.sql sql/
COPY ${flyway.confdir}/flyway.conf conf/
CMD java -XX:MaxRAMPercentage=75 -jar \
    maven/jar/${project.name}-${project.version}.jar \
    -url=jdbc:mysql://host.docker.internal:${db.port}/${db.name} \
    -user=${db.username} \
    -password=${db.password} \
    -configFiles=conf/flyway.conf \
    -jarDirs="" \
    migrate
```
***


#### ポイント
①作成したjarは2階層目に配置する。

```dockerfile
COPY maven /maven/jar/
COPY ${flyway.sqldir}/V1__Initialize.sql sql/
COPY ${flyway.confdir}/flyway.conf conf/
```

flywayの仕組みとして、sqlやconfファイルを探しに行く時2階層上のフォルダを見に行く。
以下のようなディレクトリ構造にする。

```
/
├sql
│ └V1__Initialize.sql
├conf
│ └flyway.conf
├maven
  └jar
    └flyway.jar
```

***

②sqlやconfファイルをコピーする時はpom.xmlのpropertiesを活用する。

```xml:pom.xml
...
  <properties>
    <flyway.sqldir>${project.basedir}/src/main/resources/db/migration</flyway.sqldir>
    <flyway.confdir>${project.basedir}/src/local/resources</flyway.confdir>
  </properties>
...
```
Dockerfileに直接記述した場合、意図しないパスを参照してしまう。
propertiesで宣言して参照するパスを固定化する。

***


③flywayのjarを作成する時に著名ファイルを取り除く

```xml:pom.xml
...
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>3.2.1</version>
        <configuration>
          <filters>
            <filter>
              <artifact>*:*</artifact>
              <excludes>
                <exclude>META-INF/*.SF</exclude>
                <exclude>META-INF/*.DSA</exclude>
                <exclude>META-INF/*.RSA</exclude>
              </excludes>
            </filter>
...
```
上記のプラグインを導入する。これがないとSecurityExceptionが発生する。


### docker runでmigrate実行

```zsh
mvn package docker:buid
```
dockerImageが作成される。

```zsh
docker run ${project.name}
```
でmigrateが実行される。

***

### 参考文献

http://dmp.fabric8.io/#docker:build

https://stackoverflow.com/questions/43525202/how-to-copy-files-from-an-absolute-path-to-docker-image-using-docker-maven-plugi

https://www.tssol.net/blog/2019/10/26/java_lang_securityexception_invalid-signature-file-digest-for-manifest-main-attributes/

https://oboe2uran.hatenablog.com/entry/2015/10/21/120700