英文:
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 中,以便构建步骤在容器内部完成?
编辑:
我希望用户执行以下步骤:
- 从
GitHub
克隆我的项目 - 运行
docker build -t pokerstats .
- 这将执行 gradle 构建 - 运行
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:
- Clone my project from
github
- run
docker build -t pokerstats .
- which will do the gradle build - 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 && useradd -r -g user -u 1000 user
RUN chown -R user:user /app
USER user
ENTRYPOINT exec java -jar ${ARTIFACT_NAME}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论