【问题标题】:Docker how to recompile jar file with mavenDocker如何用maven重新编译jar文件
【发布时间】:2021-04-15 09:15:53
【问题描述】:

我是 docker 新手,我正在尝试为 spring boot 项目设置 docker。

这是我的 Dockerfile

FROM maven:3.6.3-jdk-11-slim AS build
WORKDIR usr/src/springboot
COPY . ./
RUN mvn install
RUN mvn clean package 
#
# Package stage
#
FROM openjdk:11-jre-slim 
ARG JAR_NAME="springboot-0.0.1-SNAPSHOT"
WORKDIR /usr/src/springboot
EXPOSE 8080
COPY --from=build /usr/src/springboot/target/${JAR_NAME}.jar ./springboot.jar
CMD ["java","-jar", "./springboot.jar"]

完全正常,我可以从 localhost:8080 访问 hello world

但我的困惑是如何使 java 文件中的任何更改反映在 docker 容器中?如何重新编译 .jar 文件。

我尝试过类似docker exec -it strange_shaw "mvn clean package"

但它会抛出错误exec: "mvn clean package": executable file not found in $PATH: unknown

【问题讨论】:

  • installclean package没有意义
  • 尝试 mvn clean install
  • 只有mvn verify 就足够了。除此之外还有一个问题:你需要在容器内构建吗?我建议在容器外构建(只是更快),然后将最终的 jar 复制到容器中。此外,您可以配置<build><finalName>${project.artifactId}</finalName>..,并且您总是得到target/aname,而没有简化与容器配合的版本...
  • @khmarbaise 是的,我想在容器外构建。执行此操作的命令是什么?
  • mvn clean verify?

标签: java docker maven


【解决方案1】:

当您在 Dockerfile 中使用双 FROM 指令时,Docker 将只保留最新的 FROM 和使用前一个 FROM 构建下一个。

所以很容易找到这个错误,因为FROM maven:3.6.3-jdk-11-slim AS build只用来构建下一步FROM openjdk:11-jre- slim 并将从最终图像中删除(此策略用于最小化 docker 图像大小)。

我希望能给你一个关于多阶段 Dockerfile 的清晰概念。

【讨论】:

  • 那么我该如何声明maven呢?
  • 您只需要在第二个 FROM 之前的第一个阶段内执行此操作。
  • 如果我对 java 文件进行任何更改,我不应该再次重新创建整个图像,这对我来说没有意义。我只想用maven重新编译jar文件并将其复制到容器中。那么我需要在 dockerfile 中做哪些更改呢?
  • 是的,如果您使用 IDE(intellij、eclipse)在外部构建 jar 文件,您可以只保留包阶段:
  • 你需要重建整个镜像,就像你需要重建整个.jar文件一样。
【解决方案2】:

在你的 Dockerfile 变成这样之后,在外面构建你的 jar:

FROM openjdk:11-jre-slim 
ARG JAR_NAME="springboot-0.0.1-SNAPSHOT"
WORKDIR /usr/src/springboot
EXPOSE 8080
COPY /usr/src/springboot/target/${JAR_NAME}.jar ./springboot.jar
CMD ["java","-jar", "./springboot.jar"]

【讨论】:

    【解决方案3】:

    问题是容器中没有安装 maven。所以我将我的 Dockerfile 更改为

    FROM openjdk:11
    ARG JAR_NAME="springboot-0.0.1-SNAPSHOT"
    WORKDIR /usr/src/springboot
    EXPOSE 8080
    #COPY --from=build /usr/src/springboot/target/${JAR_NAME}.jar ./springboot.jar
    #CMD ["java","-jar", "./springboot.jar"]
    RUN apt-get update; apt-get install curl -y
    
    ARG MAVEN_VERSION=3.6.3
    
    # 2- Define a constant with the working directory
    ARG USER_HOME_DIR="/root"
    
    # 4- Define the URL where maven can be downloaded from
    ARG BASE_URL=https://apache.osuosl.org/maven/maven-3/${MAVEN_VERSION}/binaries
    
    # 5- Create the directories, download maven, validate the download, install it, remove downloaded file and set links
    RUN mkdir -p /usr/share/maven /usr/share/maven/ref \
      && echo "Downloading maven" \
      && curl -fsSL -o /tmp/apache-maven.tar.gz ${BASE_URL}/apache-maven-${MAVEN_VERSION}-bin.tar.gz \
      \
      && echo "Unziping maven" \
      && tar -xzf /tmp/apache-maven.tar.gz -C /usr/share/maven --strip-components=1 \
      \
      && echo "Cleaning and setting links" \
      && rm -f /tmp/apache-maven.tar.gz \
      && ln -s /usr/share/maven/bin/mvn /usr/bin/mvn
    
    # 6- Define environmental variables required by Maven, like Maven_Home directory and where the maven repo is located
    ENV MAVEN_HOME /usr/share/maven
    ENV MAVEN_CONFIG "$USER_HOME_DIR/.m2"
    

    这将在容器内安装 maven 并设置 $PATH

    docker run -it -v "$(pwd)":/usr/src/springboot -p 8080:8080 spring-boot-app
    

    运行上面的命令来启动容器并将你的项目文件夹映射到容器文件夹和本地端口到容器端口。因此,如果您对项目进行任何更改,两者都是同步的。

    docker exec -it <container_name> mvn verify
    

    以上命令将创建 .jar 文件。重启容器。

    docker exec -it <container_name> java -jar target/<file_name>.jar
    

    将在 8080 端口执行 jar 文件,并可在您的 localhost:8080 中访问

    【讨论】:

      猜你喜欢
      • 2016-12-05
      • 2011-03-22
      • 2016-07-21
      • 2012-03-23
      • 2014-12-05
      • 2014-12-27
      • 1970-01-01
      • 2016-10-03
      • 2014-07-12
      相关资源
      最近更新 更多