CodeGym /Courses /Module 5. Spring /Lecture 159: Containerizing a Project with Docker

Lecture 159: Containerizing a Project with Docker

Module 5. Spring
Level 25 , Lesson 8
Available

Before we start using Docker, let’s recall its key components:

Term Description
Dockerfile A file with instructions that describe how to build a Docker image
Image A snapshot of an app with its entire environment. Created from a Dockerfile
Container A running copy of a Docker image, launched as a separate process
Registry A repository where images are stored (e.g., Docker Hub)

Step 1: Preparing the Dockerfile

Dockerfile — is the recipe used to build a Docker image. For our Spring Boot app it will look like this:


# Use base image with Java 17
FROM openjdk:17-jdk-slim

# Set the working directory inside the container
WORKDIR /app

# Copy our compiled JAR into the container
COPY target/myapp-0.0.1-SNAPSHOT.jar app.jar

# Specify the command to run the app
ENTRYPOINT ["java", "-jar", "app.jar"]

Dockerfile structure

  1. FROM: Specifies the base image. In our case it's Java 17. Later, when you change the JDK version, just replace this line.
  2. WORKDIR: Sets the working directory inside the container where our code will run.
  3. COPY: Copies the myapp-0.0.1-SNAPSHOT.jar file from the current folder into the container.
  4. ENTRYPOINT: Defines the command that runs when the container starts.

Note: Before building the Docker image make sure your Spring Boot project is built with mvn clean package or ./gradlew bootJar. The JAR file is created in target or build/libs.


Step 2: Building the Docker image

Now that our Dockerfile is ready, let's build the Docker image. Open a terminal in the project's root folder (where the Dockerfile is) and run:


docker build -t myapp .

Let's break down the command just in case:

  • docker build: The instruction for Docker to build the image.
  • -t myapp: Specifies the name for the image (myapp).
  • .: Uses the current directory as the build context.

If everything went right, you'll see something like:
Successfully built <image-id>
Successfully tagged myapp:latest

You can check the built image with:


docker images

Step 3: Running the container

You run a container from the image with the docker run command. Here's how:


docker run -p 8080:8080 myapp

In that command:

  • -p 8080:8080: Maps container port 8080 to the host machine.
  • myapp: The name of our image.

If everything worked, your app will be available at: http://localhost:8080. Congrats — you just ran your Spring Boot app in a container!


Step 4: Optimizing the Dockerfile

Your Docker image is working, but it might be heavy and slow to deploy. Let's optimize it!

We'll use a multi-stage build:


# Stage 1: Build the app
FROM maven:3.8.5-openjdk-17 AS builder
WORKDIR /build
COPY pom.xml .
COPY src ./src
RUN mvn clean package -DskipTests

# Stage 2: Create a lightweight image
FROM openjdk:17-jdk-slim
WORKDIR /app
COPY --from=builder /build/target/myapp-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]

Now we use Maven only during the build stage, and for running the app we use the lightweight image openjdk:17-jdk-slim. This significantly reduces the final Docker image size.


Step 5: Publishing the Docker image

To share your image or deploy it on a server you need to push it to a Docker Registry. The most popular one is Docker Hub.

1. Log in to Docker Hub:


docker login

2. Tag the image (replace username with your Docker Hub username):


docker tag myapp username/myapp:latest

3. Push the image:


docker push username/myapp:latest

Now the image is available to pull:

docker pull username/myapp:latest

Step 6: Troubleshooting

When working with containers you may run into a few issues:

  1. JAR file not found: Make sure you've built the project before running docker build.
  2. Port conflicts: If port 8080 is taken, use another one, for example:
    
    docker run -p 9090:8080 myapp
    
  3. Huge image size: Use lightweight base images (for example, openjdk:17-jdk-slim).
  4. Can't access services (e.g., DB): Containers are isolated; make sure they can "see" your database. Use Docker Compose for networking.

Step 7: Using Docker Compose

If your app uses multiple services (e.g., a database + the app), you can configure them with Docker Compose.

Create a docker-compose.yml file:


version: '3.8'
services:
  app:
    build:
      context: .
    ports:
      - "8080:8080"
    depends_on:
      - db
  db:
    image: postgres:15
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
      POSTGRES_DB: myappdb

Command to run:

docker-compose up

Now Docker Compose will bring up both the app and the database at the same time!


Containerization isn't just a fad — it's a standard in modern software development. Docker images help you:

  • Quickly deploy the app to a server or the cloud.
  • Provide environment isolation and consistency.
  • Automate CI/CD pipelines.

On interviews employers will definitely value your Docker skills, and in real projects you'll save a lot of time on environment setup.

Now you've got everything you need to package and deploy your project! 🎉

Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION