Dockers 上的多模块 Maven 项目
multi-module Maven project on Dockers
我有一个多模块 Maven 项目,其中单个模块都是可运行的微服务应用程序,包含它们自己的 Dockerfile,因此在生产中每个模块都是容器化应用程序。
包含子模块的父项目仅包含父 pom.xml 和 docker-compose.yml
我尝试使用以下 Dockerfile(在子模块级别):
FROM sgrio/java-oracle
RUN apt-get update
RUN apt-get install -y maven
COPY ../pom.xml /usr/local/service/Oogaday/pom.xml
COPY pom.xml /usr/local/service/Oogaday/OogadayApi/pom.xml
COPY src /usr/local/service/Oogaday/OogadayApi/src
WORKDIR /usr/local/service/Oogaday/OogadayApi/
RUN mvn package -DskipTests
CMD ["java","-jar","org.oogaday.api-1.0-SNAPSHOT-jar-with-dependencies.jar"]
但是我遇到了一个安全错误,因为我正在尝试复制父 pom.xml 文件(它不在我 运行 构建所在的目录中)。
那么有没有办法用父 pom 构建基于 maven 的子模块?
这是我的建议,您应该尽可能多地利用 docker 缓存。
假设这个多模块项目 pom 布局:
+-- my-project
+-- module1
| `-- pom.xml
+-- module2
| `-- pom.xml
`- pom.xml
Docker 文件:
# cache as most as possible in this multistage dockerfile.
FROM maven:3.6-alpine as DEPS
WORKDIR /opt/app
COPY module1/pom.xml module1/pom.xml
COPY module2/pom.xml module2/pom.xml
# you get the idea:
# COPY moduleN/pom.xml moduleN/pom.xml
COPY pom.xml .
RUN mvn -B -e -C org.apache.maven.plugins:maven-dependency-plugin:3.1.2:go-offline
# if you have modules that depends each other, you may use -DexcludeArtifactIds as follows
# RUN mvn -B -e -C org.apache.maven.plugins:maven-dependency-plugin:3.1.2:go-offline -DexcludeArtifactIds=module1
# Copy the dependencies from the DEPS stage with the advantage
# of using docker layer caches. If something goes wrong from this
# line on, all dependencies from DEPS were already downloaded and
# stored in docker's layers.
FROM maven:3.6-alpine as BUILDER
WORKDIR /opt/app
COPY --from=deps /root/.m2 /root/.m2
COPY --from=deps /opt/app/ /opt/app
COPY module1/src /opt/app/module1/src
COPY module2/src /opt/app/module2/src
# use -o (--offline) if you didn't need to exclude artifacts.
# if you have excluded artifacts, then remove -o flag
RUN mvn -B -e -o clean install -DskipTests=true
# At this point, BUILDER stage should have your .jar or whatever in some path
FROM openjdk:8-alpine
WORKDIR /opt/app
COPY --from=builder /opt/app/<path-to-target>/my-1.0.0.jar .
EXPOSE 8080
CMD [ "java", "-jar", "/opt/app/my-1.0.0.jar" ]
我有一个多模块 Maven 项目,其中单个模块都是可运行的微服务应用程序,包含它们自己的 Dockerfile,因此在生产中每个模块都是容器化应用程序。
包含子模块的父项目仅包含父 pom.xml 和 docker-compose.yml
我尝试使用以下 Dockerfile(在子模块级别):
FROM sgrio/java-oracle
RUN apt-get update
RUN apt-get install -y maven
COPY ../pom.xml /usr/local/service/Oogaday/pom.xml
COPY pom.xml /usr/local/service/Oogaday/OogadayApi/pom.xml
COPY src /usr/local/service/Oogaday/OogadayApi/src
WORKDIR /usr/local/service/Oogaday/OogadayApi/
RUN mvn package -DskipTests
CMD ["java","-jar","org.oogaday.api-1.0-SNAPSHOT-jar-with-dependencies.jar"]
但是我遇到了一个安全错误,因为我正在尝试复制父 pom.xml 文件(它不在我 运行 构建所在的目录中)。
那么有没有办法用父 pom 构建基于 maven 的子模块?
这是我的建议,您应该尽可能多地利用 docker 缓存。
假设这个多模块项目 pom 布局:
+-- my-project
+-- module1
| `-- pom.xml
+-- module2
| `-- pom.xml
`- pom.xml
Docker 文件:
# cache as most as possible in this multistage dockerfile.
FROM maven:3.6-alpine as DEPS
WORKDIR /opt/app
COPY module1/pom.xml module1/pom.xml
COPY module2/pom.xml module2/pom.xml
# you get the idea:
# COPY moduleN/pom.xml moduleN/pom.xml
COPY pom.xml .
RUN mvn -B -e -C org.apache.maven.plugins:maven-dependency-plugin:3.1.2:go-offline
# if you have modules that depends each other, you may use -DexcludeArtifactIds as follows
# RUN mvn -B -e -C org.apache.maven.plugins:maven-dependency-plugin:3.1.2:go-offline -DexcludeArtifactIds=module1
# Copy the dependencies from the DEPS stage with the advantage
# of using docker layer caches. If something goes wrong from this
# line on, all dependencies from DEPS were already downloaded and
# stored in docker's layers.
FROM maven:3.6-alpine as BUILDER
WORKDIR /opt/app
COPY --from=deps /root/.m2 /root/.m2
COPY --from=deps /opt/app/ /opt/app
COPY module1/src /opt/app/module1/src
COPY module2/src /opt/app/module2/src
# use -o (--offline) if you didn't need to exclude artifacts.
# if you have excluded artifacts, then remove -o flag
RUN mvn -B -e -o clean install -DskipTests=true
# At this point, BUILDER stage should have your .jar or whatever in some path
FROM openjdk:8-alpine
WORKDIR /opt/app
COPY --from=builder /opt/app/<path-to-target>/my-1.0.0.jar .
EXPOSE 8080
CMD [ "java", "-jar", "/opt/app/my-1.0.0.jar" ]