Java 如何将maven项目dockerize?有多少种方法可以实现这一目标?

Java 如何将maven项目dockerize?有多少种方法可以实现这一目标?,java,maven,docker,Java,Maven,Docker,我是Docker新手,不知道如何使用maven运行java项目,尽管我已经阅读了许多文档并尝试了许多方法 我应该使用Dockerfile构建映像吗 使用Dockerfile在主机中运行maven项目时,命令是什么样子的 根据经验,您应该使用Maven(一个包含代码和所有依赖项的JAR)构建一个胖JAR 然后,您可以编写一个符合您需求的Dockerfile(如果您可以构建一个胖JAR,那么您只需要一个基本操作系统,比如CentOS和JVM) 这就是我用于Scala应用程序(基于Java)的内容 这

我是Docker新手,不知道如何使用maven运行java项目,尽管我已经阅读了许多文档并尝试了许多方法

  • 我应该使用
    Dockerfile
    构建映像吗
  • 使用
    Dockerfile
    在主机中运行maven项目时,命令是什么样子的

  • 根据经验,您应该使用Maven(一个包含代码和所有依赖项的JAR)构建一个胖JAR

    然后,您可以编写一个符合您需求的Dockerfile(如果您可以构建一个胖JAR,那么您只需要一个基本操作系统,比如CentOS和JVM)

    这就是我用于Scala应用程序(基于Java)的内容

    这将使用Java7创建一个基于CentOS的映像。 启动时,它将执行您的应用程序jar

    部署它的最佳方式是通过Docker注册表,它就像Docker映像的Github

    您可以构建如下图像:

    # current dir must contain the Dockerfile
    docker build -t username/projectname:tagname .
    
    然后,您可以通过以下方式推送图像:

    docker push username/projectname # this pushes all tags
    
    一旦图像在Docker注册表中,您就可以从世界任何地方提取并运行它

    有关更多信息,请参阅

    要记住的东西

    您也可以将存储库拉入映像中,并作为容器执行的一部分构建jar,但这不是一个好方法,因为代码可能会发生变化,您可能会在没有通知的情况下使用不同版本的应用程序

    构建胖罐子可以解决这个问题。

    工作示例。 这不是spring引导教程。这是关于如何在Docker容器中运行Maven构建的问题的更新答案

    这个问题最初发表于4年前

    1.生成应用程序 使用spring初始值设定项生成演示应用程序

    在本地解压缩zip存档

    2.创建Dockerfile 注

    • 本例使用了一个。第一阶段用于构建代码。第二个阶段只包含构建的jar和运行它的JRE(注意jar是如何在阶段之间复制的)
    3.树立形象 4.运行映像 杂项 阅读Docker hub文档,了解如何优化Maven构建以使用本地存储库缓存JAR


    更新(2019-02-07) 这个问题已经提出4年了,可以公平地说,使用Docker构建应用程序已经经历了重大的变化

    选项1:多阶段构建 这种新样式使您能够创建更轻量级的图像,而不封装构建工具和源代码

    这里的示例再次使用基本映像,使用所需版本的Maven运行构建的第一阶段。文件的第二部分定义了如何将构建的jar组装到最终的输出图像中

    FROM maven:3.5-jdk-8 AS build  
    COPY src /usr/src/app/src  
    COPY pom.xml /usr/src/app  
    RUN mvn -f /usr/src/app/pom.xml clean package
    
    FROM gcr.io/distroless/java  
    COPY --from=build /usr/src/app/target/helloworld-1.0.0-SNAPSHOT.jar /usr/app/helloworld-1.0.0-SNAPSHOT.jar  
    EXPOSE 8080  
    ENTRYPOINT ["java","-jar","/usr/app/helloworld-1.0.0-SNAPSHOT.jar"]  
    
    注:

    • 我正在使用Google的基本映像,它努力为java应用程序提供足够的运行时间
    方案2:起重臂 我没有使用过这种方法,但似乎值得研究,因为它使您能够构建图像,而不必创建DockerFile之类的讨厌的东西:-)

    该项目具有一个将代码打包直接集成到Maven工作流中的功能


    原始答案(包括完整性,但写于很久以前) 尝试使用新的官方图片,Maven有一个

    该映像可用于在构建时运行Maven,以创建已编译的应用程序,或如以下示例所示,在容器中运行Maven构建

    示例1-在容器中运行的Maven 以下命令在容器中运行Maven build:

    docker run -it --rm \
           -v "$(pwd)":/opt/maven \
           -w /opt/maven \
           maven:3.2-jdk-7 \
           mvn clean install
    
    注:

    • 这种方法的好处在于,所有软件都是在容器中安装和运行的。主机上只需要docker
    示例2-使用Nexus缓存文件 运行Nexus容器

    docker run -d -p 8081:8081 --name nexus sonatype/nexus
    
    创建“settings.xml”文件:

    注:

    • 在后台运行Nexus的一个优点是,其他第三方存储库可以通过管理员URL进行管理,对本地容器中运行的Maven构建是透明的

      • 可能有很多方法。。但我通过以下两种方式实现

        给出的例子是maven项目

        1。在maven项目中使用Dockerfile

        使用以下文件结构:

        Demo
        └── src
        |    ├── main
        |    │   ├── java
        |    │       └── org
        |    │           └── demo
        |    │               └── Application.java
        |    │   
        |    └── test
        |
        ├──── Dockerfile
        ├──── pom.xml
        
        并将Dockerfile更新为:

        FROM java:8
        EXPOSE 8080
        ADD /target/demo.jar demo.jar
        ENTRYPOINT ["java","-jar","demo.jar"]
        
        导航到项目文件夹,并键入以下命令,您将看到: 要创建映像并运行该映像,请执行以下操作:

        $ mvn clean
        $ mvn install
        $ docker build -f Dockerfile -t springdemo .
        $ docker run -p 8080:8080 -t springdemo
        
        $ mvn clean package docker:build
        $ docker images
        $ docker run -p 8080:8080 -t <image name>
        

        2。使用Maven插件

        pom.xml

        <plugin>
            <groupId>com.spotify</groupId>
            <artifactId>docker-maven-plugin</artifactId>
            <version>0.4.5</version>
                <configuration>
                    <imageName>springdocker</imageName>
                    <baseImage>java</baseImage>
                    <entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint>
                    <resources>
                        <resource>
                            <targetPath>/</targetPath>
                            <directory>${project.build.directory}</directory>
                            <include>${project.build.finalName}.jar</include>
                        </resource>
                    </resources>
                </configuration>
            </plugin>
        
        
        com.spotify
        docker maven插件
        0.4.5
        斯普林多克
        JAVA
        [“java”、“-jar”、“/${project.build.finalName}.jar”]
        /
        ${project.build.directory}
        ${project.build.finalName}.jar
        
        导航到项目文件夹并键入以下命令,您将能够创建图像并运行该图像:

        $ mvn clean
        $ mvn install
        $ docker build -f Dockerfile -t springdemo .
        $ docker run -p 8080:8080 -t springdemo
        
        $ mvn clean package docker:build
        $ docker images
        $ docker run -p 8080:8080 -t <image name>
        
        $mvn干净包docker:build
        $docker图像
        $docker run-p 8080:8080-t
        
        在第一个示例中,我们创建Dockerfile并提供基本映像并添加jar,这样做之后,我们将运行docker命令以构建具有特定名称的映像,然后运行该映像


        而在第二个示例中,我们使用maven插件,其中我们提供了
        baseImage
        imageName
        ,因此不需要在这里创建Dockerfile。。打包maven项目后,我们将获得docker映像,我们只需要运行该映像。

        以下是我的贡献。
        我不会试图列出所有利用Docker with Maven的工具/库/插件。一些答案已经做到了。
        我将重点介绍应用程序类型和Dockerfile方式,而不是
        FROM java:8
        EXPOSE 8080
        ADD /target/demo.jar demo.jar
        ENTRYPOINT ["java","-jar","demo.jar"]
        
        $ mvn clean
        $ mvn install
        $ docker build -f Dockerfile -t springdemo .
        $ docker run -p 8080:8080 -t springdemo
        
        <plugin>
            <groupId>com.spotify</groupId>
            <artifactId>docker-maven-plugin</artifactId>
            <version>0.4.5</version>
                <configuration>
                    <imageName>springdocker</imageName>
                    <baseImage>java</baseImage>
                    <entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint>
                    <resources>
                        <resource>
                            <targetPath>/</targetPath>
                            <directory>${project.build.directory}</directory>
                            <include>${project.build.finalName}.jar</include>
                        </resource>
                    </resources>
                </configuration>
            </plugin>
        
        $ mvn clean package docker:build
        $ docker images
        $ docker run -p 8080:8080 -t <image name>
        
        ########Maven build stage########
        FROM maven:3.6-jdk-11 as maven_build
        WORKDIR /app
        
        #copy pom
        COPY pom.xml .
        
        #resolve maven dependencies
        RUN mvn clean package -Dmaven.test.skip -Dmaven.main.skip -Dspring-boot.repackage.skip && rm -r target/
        
        #copy source
        COPY src ./src
        
        # build the app (no dependency download here)
        RUN mvn clean package  -Dmaven.test.skip
        
        # split the built app into multiple layers to improve layer rebuild
        RUN mkdir -p target/docker-packaging && cd target/docker-packaging && jar -xf ../my-app*.jar
        
        ########JRE run stage########
        FROM openjdk:11.0-jre
        WORKDIR /app
        
        #copy built app layer by layer
        ARG DOCKER_PACKAGING_DIR=/app/target/docker-packaging
        COPY --from=maven_build ${DOCKER_PACKAGING_DIR}/BOOT-INF/lib /app/lib
        COPY --from=maven_build ${DOCKER_PACKAGING_DIR}/BOOT-INF/classes /app/classes
        COPY --from=maven_build ${DOCKER_PACKAGING_DIR}/META-INF /app/META-INF
        
        #run the app
        CMD java -cp .:classes:lib/* \
                 -Djava.security.egd=file:/dev/./urandom \
                 foo.bar.MySpringBootApplication
        
        # syntax=docker/dockerfile:experimental
        
        ########Maven build stage########
        FROM maven:3.6-jdk-11 as maven_build
        WORKDIR /app
        
        #copy pom
        COPY pom.xml .
            
        #copy source
        COPY src ./src
        
        # build the app and download dependencies only when these are new (thanks to the cache)
        RUN --mount=type=cache,target=/root/.m2  mvn clean package -Dmaven.test.skip
        
        # split the built app into multiple layers to improve layer rebuild
        RUN mkdir -p target/docker-packaging && cd target/docker-packaging && jar -xf ../my-app*.jar
        
        ########JRE run stage########
        FROM openjdk:11.0-jre
        WORKDIR /app
        
        #copy built app layer by layer
        ARG DOCKER_PACKAGING_DIR=/app/target/docker-packaging
        COPY --from=maven_build ${DOCKER_PACKAGING_DIR}/BOOT-INF/lib /app/lib
        COPY --from=maven_build ${DOCKER_PACKAGING_DIR}/BOOT-INF/classes /app/classes
        COPY --from=maven_build ${DOCKER_PACKAGING_DIR}/META-INF /app/META-INF
        
        #run the app
        CMD java -cp .:classes:lib/* \
                 -Djava.security.egd=file:/dev/./urandom \
                 foo.bar.MySpringBootApplication
        
                                                                                                                                                                                
                                                                               
                                                                               
        
        Create a Dockerfile
        #
        # Build stage
        #
        
        FROM maven:3.6.3-jdk-11-slim AS build
        
        WORKDIR usr/src/app
        
        COPY . ./
        
        RUN mvn clean package
        
        #
        # Package stage
        #
        
        FROM openjdk:11-jre-slim
        
        ARG JAR_NAME="project-name"
        
        WORKDIR /usr/src/app
        
        EXPOSE ${HTTP_PORT}
        
        COPY --from=build /usr/src/app/target/${JAR_NAME}.jar ./app.jar
        
        CMD ["java","-jar", "./app.jar"]
        
        ...
        <properties>
            <java.version>11</java.version>
            <docker.name>amirkeshavarz/hellomavendocker</docker.name>
            <docker.REGISTRY_USERNAME>your-dockerhub-username</docker.REGISTRY_USERNAME>
            <docker.REGISTRY_PASSWORD>your-dockerhub-password</docker.REGISTRY_PASSWORD>
        </properties>
        ...
        <build>
            <plugins>
                ...
                <plugin>
                    <groupId>com.google.cloud.tools</groupId>
                    <artifactId>jib-maven-plugin</artifactId>
                    <version>2.8.0</version>
                    <configuration>
                        <from>
                            <image>openjdk:17-jdk-alpine</image>
                            <auth>
                                <username>${docker.REGISTRY_USERNAME}</username>
                                <password>${docker.REGISTRY_PASSWORD}</password>
                            </auth>
                        </from>
                        <to>
                            <image>${docker.name}</image>
                            <auth>
                                <username>${docker.REGISTRY_USERNAME}</username>
                                <password>${docker.REGISTRY_PASSWORD}</password>
                            </auth>
                        </to>
                        <container>
                            <environment></environment>
                            <ports>
                                <port>8080</port>
                            </ports>
                            <creationTime>USE_CURRENT_TIMESTAMP</creationTime>
                        </container>
                    </configuration>
                    <executions>
                        <execution>
                            <phase>package</phase>
                            <goals>
                                <goal>build</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
        ...