Gradle和Docker:如何在Docker容器中运行Gradle构建?

huangapple go评论71阅读模式
英文:

Gradle and Docker: How to run a Gradle build within Docker container?

问题

以下是翻译好的部分:

# 选择 Java 11 镜像
FROM adoptopenjdk/openjdk11:alpine-jre

# 定义 JAR 文件路径
ARG JAR_FILE=/build/libs/pokerstats-0.0.1-SNAPSHOT.jar

# 设置工作目录
WORKDIR /opt/app

# 复制 JAR 文件到容器内
COPY ${JAR_FILE} app.jar

# 指定入口命令
ENTRYPOINT ["java","-jar","app.jar"]

问题在于目前我必须先在主机上运行 gradle clean build,以便在本地机器上创建位于以下路径的 JAR 文件:

/build/libs/pokerstats-0.0.1-SNAPSHOT.jar

我如何将 gradle clean build 添加到我的 Dockerfile 中,以便构建步骤在容器内部完成?

编辑:

我希望用户执行以下步骤:

  1. GitHub 克隆我的项目
  2. 运行 docker build -t pokerstats . - 这将执行 gradle 构建
  3. 运行 docker container run -d -p 8080:8080 pokerstats

用户将从 GitHub 克隆我的项目 - 然后我希望他们能够在不必先使用 gradle 构建项目的情况下运行 Docker 容器,即我希望 Dockerfile 完成构建并将 JAR 文件复制到容器中。

英文:

I have the following docker file that runs a spring boot application:

# For Java 11, try this
FROM adoptopenjdk/openjdk11:alpine-jre

#
ARG JAR_FILE=/build/libs/pokerstats-0.0.1-SNAPSHOT.jar

#
WORKDIR /opt/app

#
COPY ${JAR_FILE} app.jar

#
ENTRYPOINT ["java","-jar","app.jar"]

The issue is that currently I have to run gradle clean build on my host machine first to create the jar file on my local machine at path:

/build/libs/pokerstats-0.0.1-SNAPSHOT.jar

How can I put this gradle clean build into my docker file so that the build step is done inside the container?

edit:

I want the steps for a user to be:

  1. Clone my project from github
  2. run docker build -t pokerstats . - which will do the gradle build
  3. run docker container run -d -p 8080:8080 pokerstats

The user will clone my project from github - I then want them to be able to run the docker container without having to build the project with gradle first - I.e. I want the docker file to do the build and copy the jar into the container.

答案1

得分: 28

阅读了这篇文章之后,我已经能够通过使用多阶段 Docker 构建来解决这个问题。请参阅下面的 Dockerfile:

# 使用多阶段 Docker 构建
# 参考:https://docs.docker.com/develop/develop-images/multistage-build/
    
# 临时容器用于使用 gradle 进行构建
FROM gradle:5.3.0-jdk-alpine AS TEMP_BUILD_IMAGE
ENV APP_HOME=/usr/app/
WORKDIR $APP_HOME
COPY build.gradle settings.gradle $APP_HOME
  
COPY gradle $APP_HOME/gradle
COPY --chown=gradle:gradle . /home/gradle/src
USER root
RUN chown -R gradle /home/gradle/src
    
RUN gradle build || return 0
COPY . .
RUN gradle clean build
    
# 实际容器
FROM adoptopenjdk/openjdk11:alpine-jre
ENV ARTIFACT_NAME=pokerstats-0.0.1-SNAPSHOT.jar
ENV APP_HOME=/usr/app/
    
WORKDIR $APP_HOME
COPY --from=TEMP_BUILD_IMAGE $APP_HOME/build/libs/$ARTIFACT_NAME .
    
EXPOSE 8080
ENTRYPOINT exec java -jar ${ARTIFACT_NAME}
英文:

After reading this article I have been able to solve this using a Multi Stage Docker Build. Please see the Docker file below:

# using multistage docker build
# ref: https://docs.docker.com/develop/develop-images/multistage-build/
    
# temp container to build using gradle
FROM gradle:5.3.0-jdk-alpine AS TEMP_BUILD_IMAGE
ENV APP_HOME=/usr/app/
WORKDIR $APP_HOME
COPY build.gradle settings.gradle $APP_HOME
  
COPY gradle $APP_HOME/gradle
COPY --chown=gradle:gradle . /home/gradle/src
USER root
RUN chown -R gradle /home/gradle/src
    
RUN gradle build || return 0
COPY . .
RUN gradle clean build
    
# actual container
FROM adoptopenjdk/openjdk11:alpine-jre
ENV ARTIFACT_NAME=pokerstats-0.0.1-SNAPSHOT.jar
ENV APP_HOME=/usr/app/
    
WORKDIR $APP_HOME
COPY --from=TEMP_BUILD_IMAGE $APP_HOME/build/libs/$ARTIFACT_NAME .
    
EXPOSE 8080
ENTRYPOINT exec java -jar ${ARTIFACT_NAME}

答案2

得分: 4

# 构建阶段
FROM gradle:latest AS BUILD
WORKDIR /usr/app/
COPY . .
RUN gradle build

# 打包阶段
FROM openjdk:latest
ENV JAR_NAME=app.jar
ENV APP_HOME=/usr/app/
WORKDIR $APP_HOME
COPY --from=BUILD $APP_HOME .
EXPOSE 8080
ENTRYPOINT exec java -jar $APP_HOME/build/libs/$JAR_NAME

请确保将 JAR_NAME 变量更改为您生成的 JAR 文件的名称。

英文:

Mutli stage build. Be sure to have build.gradle and settings.gradle files included in your project directory, I tried to make it as clean and concise as possible:

<!-- begin snippet -->
#Build stage

FROM gradle:latest AS BUILD
WORKDIR /usr/app/
COPY . . 
RUN gradle build

# Package stage

FROM openjdk:latest
ENV JAR_NAME=app.jar
ENV APP_HOME=/usr/app/
WORKDIR $APP_HOME
COPY --from=BUILD $APP_HOME .
EXPOSE 8080
ENTRYPOINT exec java -jar $APP_HOME/build/libs/$JAR_NAME  

<!-- end snippet -->

Make sure to change JAR_NAME variable to your generated jar file name.

答案3

得分: 1

构建阶段

FROM gradle:jdk11-alpine AS BUILD_STAGE
COPY --chown=gradle:gradle . /home/gradle
RUN gradle build || return 1

打包阶段

FROM openjdk:11.0.11-jre
ENV ARTIFACT_NAME=app.jar
ENV APP_HOME=/app
COPY --from=BUILD_STAGE /home/gradle/build/libs/$ARTIFACT_NAME $APP_HOME/
WORKDIR $APP_HOME
RUN groupadd -r -g 1000 user && useradd -r -g user -u 1000 user
RUN chown -R user:user /app
USER user
ENTRYPOINT exec java -jar ${ARTIFACT_NAME}
英文:

Build stage

FROM gradle:jdk11-alpine AS BUILD_STAGE
COPY --chown=gradle:gradle . /home/gradle
RUN gradle build || return 1

Package stage

FROM openjdk:11.0.11-jre
ENV ARTIFACT_NAME=app.jar
ENV APP_HOME=/app
COPY --from=BUILD_STAGE /home/gradle/build/libs/$ARTIFACT_NAME $APP_HOME/
WORKDIR $APP_HOME
RUN groupadd -r -g 1000 user &amp;&amp; useradd -r -g user -u 1000 user
RUN chown -R user:user /app
USER user
ENTRYPOINT exec java -jar ${ARTIFACT_NAME}

huangapple
  • 本文由 发表于 2020年4月9日 02:56:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/61108021.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定