Docker上的多模块Maven项目

时间:2018-08-03 19:57:38

标签: java maven docker pom.xml microservices

我有一个多模块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的子模块?

2 个答案:

答案 0 :(得分:4)

这是我的建议,您应该更多地利用docker缓存。

假定此多模块项目pom布局:

+-- my-project
   +-- module1
   |   `-- pom.xml
   +-- module2
   |   `-- pom.xml
    `- pom.xml

Dockerfile:

# 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" ]

答案 1 :(得分:0)

This thread中,讨论了在构建docker映像时从父目录添加文件的情​​况。

无论如何,我认为这不是一个好的方法,也许以下替代方法会更好:

一个想法:

请勿在docker映像构建过程中运行“ maven””,在这种简单情况下,此方法可能会起作用,但是如果您要在根项目模块(构建映像)下添加以设置“ commons”模块,该怎么办脚本将变得更加复杂,此外,可能很难将结果图像中的层数保持在最低水平。

考虑在构建机器中的docker外部运行常规mvn软件包 准备好工件后,只需将工件添加到所需的文件夹并运行该应用程序,即可对其进行构建。

这样,您在构建docker映像时无需考虑maven依赖关系,maven知道了其依赖关系并能够构建工件

已经说过,如果需要在映像创建过程中运行构建,则失败的主要原因是,dockre构建过程不允许访问“父”文件夹(或通常,不能访问“父”文件夹)。 docker文件所在的文件夹)。所以应该有以下可能:

Docker文件应该存在于根文件夹(根pom.xml所在的位置)中。 为了仅可能运行具有所有依赖项的所需模块的构建,应使用以下命令:

COPY <all the filesystem of the project>
mvn package --projects service --also-make

或者,如果您只需要复制服务,则可以借助mvn -f /path/to/pom.xml

指定位于其他位置的pom路径。
相关问题