Reputation: 1671
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:
github
docker build -t pokerstats .
- which will do the gradle buildThe 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.
Upvotes: 20
Views: 78891
Reputation: 231
I've been looking for solutions to build and run my own gradle project with a Dockerfile, and I finally got one that works.
# Use an appropriate base image for Java 17
FROM openjdk:17-jdk-slim
# Install dependencies
RUN apt-get update && \
apt-get install -y wget unzip
# Download Gradle 7.5.1
WORKDIR /opt
RUN wget https://services.gradle.org/distributions/gradle-7.5.1-bin.zip && \
unzip gradle-7.5.1-bin.zip
# Set environment variables for Gradle
ENV GRADLE_HOME=/opt/gradle-7.5.1
ENV PATH=$GRADLE_HOME/bin:$PATH
# Set the working directory inside the container
WORKDIR /app
# Copy your project files
COPY . .
# Build the project
RUN gradle build -x compileTestJava
ENV JAR_NAME=my-app.jar
ENV APP_HOME=/app
# Expose the application and debug ports
EXPOSE 8088 5005
# Command to run the application with JAVA_OPTS and SPRING_PROFILES_ACTIVE
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -Dspring.profiles.active=$SPRING_PROFILES_ACTIVE -jar $APP_HOME/build/libs/$JAR_NAME
"]
Upvotes: 0
Reputation: 1501
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:
#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
Make sure to change JAR_NAME variable to your generated jar file name.
Upvotes: 12
Reputation: 11
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}
Upvotes: 1
Reputation: 1671
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}
Upvotes: 34