Skip to the content.

β€œHow do you build a Docker image for a Java microservice?”


βœ… Step-by-Step: How to Build a Java Microservice Docker Image

Let’s assume your Java microservice is a Spring Boot application, and you have a jar file after building it.


πŸ”Ή 1. Build the JAR

Use Maven or Gradle to build your application:

Maven:

mvn clean package

This generates a target/my-service.jar.


πŸ”Ή 2. Create a Dockerfile

At the root of your project (next to pom.xml), create a file named Dockerfile:

# Start from a lightweight Java runtime base image
FROM openjdk:17-jdk-slim

# Set a working directory inside the container
WORKDIR /app

# Copy the built jar from local machine to the container
COPY target/my-service.jar app.jar

# Expose the port the app listens on (optional, documentation only)
EXPOSE 8080

# Run the application
ENTRYPOINT ["java", "-jar", "app.jar"]

πŸ”Ή 3. Build the Docker Image

docker build -t my-service:latest .

This command:


πŸ”Ή 4. Run the Docker Container

docker run -p 8080:8080 my-service:latest

Now your Java microservice runs in a container, accessible at localhost:8080.


πŸ“ Interview Tips – Explain Concepts Too

When asked this, go beyond steps and explain:


πŸ”Έ Why use Docker?


πŸ”Έ Base Image Choice?


πŸ”Έ Multi-Stage Build (Optional for Clean Images)

# Build stage
FROM maven:3.9.5-eclipse-temurin-17 as build
WORKDIR /build
COPY . .
RUN mvn clean package -DskipTests

# Run stage
FROM openjdk:17-jdk-slim
WORKDIR /app
COPY --from=build /build/target/my-service.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]

🟒 This avoids needing to copy the .jar manually after building β€” it builds and packages in one go.


βœ… Summary Answer for Interview

β€œTo containerize a Java microservice, I first build the jar using Maven or Gradle. Then I write a Dockerfile that starts from a slim OpenJDK base image, copies the jar, and runs it. I use docker build to build the image and docker run to launch it. For better optimization, I sometimes use a multi-stage build to avoid copying unneeded files and keep the final image clean and lightweight.”


βœ… 1. Docker image should only contain your service


βœ… 2. Microservices should not tightly couple the DB into the container

Reasons why DB should be external:

Reason Explanation
πŸ” Reusability Multiple services might connect to the same DB. You don’t want to embed it in each one.
☁️ Scalability DBs have different scaling patterns than microservices. They require different infra.
πŸ” Security DB access can be locked down separately (firewalls, IAM, etc.).
πŸ›  Configurability DB credentials/URLs should come from env vars or config maps, not hardcoded.

βœ… Correct Way: Use Environment Variables or Config Files for DB Connection

Let your app pick up DB config using application.properties or env variables like:

spring.datasource.url=${DB_URL}
spring.datasource.username=${DB_USER}
spring.datasource.password=${DB_PASS}

And pass those while running the container:

docker run -e DB_URL=jdbc:mysql://host:3306/dbname \
           -e DB_USER=root \
           -e DB_PASS=secret \
           -p 8080:8080 my-service

πŸ” What the Interviewer Expectes You to Say

Here’s a strong answer:

β€œWe build the Docker image with just the microservice code and dependencies. The database is not embedded in the image β€” it’s managed separately and connected via configuration, usually passed through environment variables. This makes the image portable and the architecture more scalable.”


If you’re using Docker Compose, you can define separate services:

version: '3'
services:
  my-service:
    image: my-service
    ports:
      - 8080:8080
    environment:
      - DB_URL=jdbc:mysql://db:3306/mydb
      - DB_USER=root
      - DB_PASS=secret

  db:
    image: mysql:8
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: mydb

βœ… Clarifying the Confusion: Docker Image vs Docker Compose

πŸ”Έ What you should say:

in docker-compose.yml, you can define both the application and the database as separate services. βœ…

But what the interviewer likely ask is:

β“β€œWhy are you configuring the database inside the Docker image?”


🧠 Core Concept

Concept Contains Purpose
🐳 Docker Image Your microservice code only Used to build a container
🧩 Docker Compose Definitions for multiple containers (app, DB, cache, etc.) Used to run multi-container systems

So yes:


βœ… What You Should say

β€œWe don’t include the database in the Docker image. The image only contains the microservice code. If needed, we use Docker Compose to spin up both the service and the DB as separate containers, where the app connects to the DB via environment variables.”


βœ… Correct docker-compose.yml Example

Here’s what a proper setup looks like:

version: '3.8'

services:
  app:
    image: my-java-service
    ports:
      - "8080:8080"
    environment:
      - DB_URL=jdbc:mysql://db:3306/mydb
      - DB_USER=root
      - DB_PASS=secret
    depends_on:
      - db

  db:
    image: mysql:8
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: mydb
    ports:
      - "3306:3306"

πŸ”Ή Notes:


βœ… Summary for Interview

β€œThe Docker image contains only the microservice. We don’t bake the DB into the image. If we want to run both the app and DB locally, we use Docker Compose to spin them up as separate services. The app connects to the DB using environment variables or config files, ensuring separation of concerns and scalability.”


What Does Docker Compose Do?

πŸ”Ή Docker Compose is a tool to define and manage multi-container Docker applications.

Instead of running each container manually one by one, Compose lets you describe all your services (app, database, cache, etc.) in a single YAML file (docker-compose.yml), and then:


In the example we discussed:

services:
  app:
    image: my-java-service
    ports:
      - "8080:8080"
    environment:
      - DB_URL=jdbc:mysql://db:3306/mydb
      - DB_USER=root
      - DB_PASS=secret
    depends_on:
      - db

  db:
    image: mysql:8
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: mydb
    ports:
      - "3306:3306"

What happens when you run:

docker-compose up
  1. Docker Compose creates a network where both containers live.
  2. It starts the db container first (because app depends on db).
  3. It starts the app container next.
  4. Inside the app container, your microservice uses the environment variable DB_URL=jdbc:mysql://db:3306/mydb to connect to the db container by its service name db (Docker Compose automatically sets up DNS for that).
  5. Both containers run simultaneously and can talk to each other via the Docker network.
  6. Ports like 8080 and 3306 are exposed to your host machine, so you can access your microservice and database outside Docker if needed.

Benefits of Docker Compose:


TL;DR

Docker Compose lets you spin up your entire app environment (Java service + DB) in one command, managing networking and dependencies, making local development and testing simple and consistent.


What Does Docker Compose Do?

πŸ”Ή Docker Compose is a tool to define and manage multi-container Docker applications.

Instead of running each container manually one by one, Compose lets you describe all your services (app, database, cache, etc.) in a single YAML file (docker-compose.yml), and then:


In the example we discussed:

services:
  app:
    image: my-java-service
    ports:
      - "8080:8080"
    environment:
      - DB_URL=jdbc:mysql://db:3306/mydb
      - DB_USER=root
      - DB_PASS=secret
    depends_on:
      - db

  db:
    image: mysql:8
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: mydb
    ports:
      - "3306:3306"

What happens when you run:

docker-compose up
  1. Docker Compose creates a network where both containers live.
  2. It starts the db container first (because app depends on db).
  3. It starts the app container next.
  4. Inside the app container, your microservice uses the environment variable DB_URL=jdbc:mysql://db:3306/mydb to connect to the db container by its service name db (Docker Compose automatically sets up DNS for that).
  5. Both containers run simultaneously and can talk to each other via the Docker network.
  6. Ports like 8080 and 3306 are exposed to your host machine, so you can access your microservice and database outside Docker if needed.

Benefits of Docker Compose:


TL;DR

Docker Compose lets you spin up your entire app environment (Java service + DB) in one command, managing networking and dependencies, making local development and testing simple and consistent.