How to Run a Maven Project Locally and with Docker Using a Multi-Stage Dockerfile

How to Run a Maven Project Locally and with Docker Using a Multi-Stage Dockerfile

If you're working with Java applications, Maven is a popular choice for managing dependencies and automating the build process. Once you have a working application, you may want to containerize it using Docker, which can make deploying your app more manageable and portable. This guide will walk you through running a Maven application manually and then show you how to package it with Docker using a multi-stage Dockerfile for an optimized final image.


Prerequisites

Before starting, ensure that you have the following installed:

  • Java Development Kit (JDK): Make sure it’s compatible with the project.

  • Apache Maven: Verify it’s installed by running mvn -v.

  • Docker: To containerize and run the application in a container.


Step 1: Clone and Set Up the Project

Since you've already cloned the project, navigate to your project directory. Here’s a quick reminder:

git clone https://github.com/your-repository/BankApp.git
cd BankApp

You should see the following structure in the project:

BankApp/
├── pom.xml
└── src/
    ├── main/
    └── test/

pom.xml contains your project’s dependencies and build instructions, while the src/ folder contains the Java source code.


Step 2: Run the Application Manually with Maven

Let's start by building and running the application manually.

Build the Application

In your project directory, run:

./mvnw clean install

or if the mvnw script isn’t available, use:

mvn clean install

This will:

  1. Download dependencies specified in pom.xml.

  2. Compile the code and run any tests.

  3. Package the application as a .jar file in the target/ directory.

After a successful build, you should see something like BankApp-0.0.1-SNAPSHOT.jar in the target/ folder.

Run the Application

To start the application, use:

java -jar target/BankApp-0.0.1-SNAPSHOT.jar

The application should now be running, and you can access it (if it’s a web app) by navigating to http://localhost:8080.


Step 3: Containerize the Application with Docker

Now, let’s make the application easier to deploy by containerizing it with Docker. A multi-stage Dockerfile will help us build and run the application more efficiently.

What is a Multi-Stage Dockerfile?

A multi-stage Dockerfile separates the build and runtime environments. We use a Maven-based image to compile the project, then copy only the compiled .jar file to a minimal Java runtime image, resulting in a smaller, more efficient Docker image.


Writing the Multi-Stage Dockerfile

In the project’s root directory, create a file named Dockerfile and add the following contents:

# Stage 1: Build the application
FROM maven:3.8.7-openjdk-17 AS build

# Set the working directory in the container
WORKDIR /app

# Copy the pom.xml and source code
COPY pom.xml .
COPY src ./src

# Build the application
RUN mvn clean install -DskipTests

# Stage 2: Run the application
FROM openjdk:17-jdk-alpine

# Set the working directory
WORKDIR /app

# Copy the jar file from the build stage
COPY --from=build /app/target/BankApp-0.0.1-SNAPSHOT.jar app.jar

# Expose the port (update if the app uses a different port)
EXPOSE 8080

# Command to run the application
CMD ["java", "-jar", "app.jar"]

Explanation of the Dockerfile

  • Stage 1 (Build Stage):

    • We use maven:3.8.7-openjdk-17 as the base image.

    • The source code and pom.xml are copied into the container.

    • The mvn clean install -DskipTests command compiles the application and skips tests for faster builds.

    • The compiled .jar file is created in /app/target.

  • Stage 2 (Runtime Stage):

    • We use a smaller image, openjdk:17-jdk-alpine, to run the app.

    • The .jar file from the build stage is copied over.

    • The container exposes port 8080 (adjust as needed).

    • The CMD instruction starts the app.


Step 4: Build and Run the Docker Image

Now that the Dockerfile is ready, let’s build and run the Docker image.

Build the Docker Image

Run the following command to build the Docker image:

docker build -t bankapp:latest .

The -t bankapp:latest option tags the image as bankapp with the latest tag.

Run the Docker Container

Start a container from the Docker image:

docker run -p 8080:81 bankapp:latest
  • The -p 81:8080 option maps port 81 on your machine to port 8080 in the container.

  • Your application should now be accessible at http://localhost:81.


Step 5: Verify the Application

To verify that everything is working:

  1. Open a web browser or use a tool like curl to access http://localhost:81.

  2. Check the logs in your terminal to ensure there are no errors.


Recap

Here’s what we covered in this guide:

  1. Manual Build and Run: Built and ran the application locally using Maven.

  2. Containerized Build and Run: Used a multi-stage Dockerfile to build a Docker image and run it in a container.

By containerizing the application, you’ve made it easier to deploy across environments consistently, without the need for a specific JDK or Maven installation. The multi-stage Dockerfile ensures the final image is optimized for size and performance, containing only what’s needed to run the application.