java12399900
java12399900

Reputation: 1671

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

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.

Upvotes: 20

Views: 78891

Answers (4)

Abbas
Abbas

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

Abdelsalam Megahed
Abdelsalam Megahed

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

Ariel
Ariel

Reputation: 11

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}

Upvotes: 1

java12399900
java12399900

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

Related Questions