Skip to main content

Command Palette

Search for a command to run...

Understanding Docker: Simplifying Spring Boot Deployment with Docker Compose

Updated
6 min read
Understanding Docker: Simplifying Spring Boot Deployment with Docker Compose
T
👋 Hi there! I'm a tech enthusiast with a passion for programming and all the exciting things that come with it. ✍️ I’m passionate about giving back to the tech community and regularly write articles sharing insights and best practices based on my experiences. 📚

As software developers, we always look for ways to streamline our development process, make deployments smoother, and ensure our applications run consistently across environments. If you’ve ever heard people rave about how Docker transformed their workflows but weren’t sure where to start, you’re in the right place.

This article breaks down Docker and Docker Compose with a hands-on Spring Boot example. By the end of this, you’ll understand the core concepts and have a working Spring Boot application containerized and running in Docker.

What is Docker?

Imagine you’re working on a project that runs perfectly on your local machine. Then, when it’s deployed on a server, all sorts of compatibility issues arise. Painful, right? Docker solves this by packaging your application and all its dependencies into a standardized unit called a container.

In simple terms:

  • Docker is a platform that allows you to automate the deployment of applications inside lightweight containers.

  • Containers are isolated environments that include everything your application needs to run — code, system tools, libraries, and settings.

Key Docker Concepts

Before jumping into the example, let’s get familiar with a few important Docker terms.

1. Image

An image is essentially a blueprint of your application and its environment. Think of it as a snapshot. Once you have a Docker image, you can run it anywhere without worrying about dependencies or system configuration.

  • Analogy: Think of an image as a pre-configured VM snapshot that can be reused.

2. Container

A container is a running instance of an image. While an image is just the blueprint, the container is the actual thing running your application.

  • Analogy: If an image is like a cake recipe, the container is the cake you bake following that recipe.

3. Dockerfile

A Dockerfile is where the magic happens! This is a text file that contains instructions on how to build a Docker image. You specify things like the base image, commands to install dependencies, and how to launch the application.

  • Analogy: Think of a Dockerfile as the instruction manual to assemble your project environment.

4. Docker Hub

Docker Hub is a cloud-based registry where you can store and share your Docker images. Developers often pull base images from here.

  • Analogy: Docker Hub is like GitHub for Docker images.

5. Volume

A volume in Docker allows you to persist data outside the container. When the container is deleted, its data is gone unless it’s stored in a volume.

  • Analogy: Think of volumes as external hard drives for your containers.

6. Docker Compose

While Docker is great for individual containers, what if your application requires multiple services, like a web server, a database, and a cache? Docker Compose allows you to define multi-container Docker applications with a single configuration file (called docker-compose.yml).

  • Analogy: Docker Compose is the conductor orchestrating an orchestra of containers to work together harmoniously.

Building a Spring Boot Application with Docker

Let’s put theory into practice by Dockerizing a simple Spring Boot application.

Step 1: Create a Spring Boot Application

If you don’t already have a Spring Boot application, you can easily generate one from start.spring.io.

Add the following dependencies:

  • Spring Web

  • Spring Data JPA

  • H2 Database

Step 2: Create a Dockerfile

In your Spring Boot project’s root directory, create a file called Dockerfile with the following contents:

# Use an official OpenJDK runtime as a parent image
FROM openjdk:17-jdk-alpine

# Set the working directory inside the container
WORKDIR /app

# Copy the current directory contents into the container at /app
COPY target/springboot-docker-compose-0.0.1-SNAPSHOT.jar /app/springboot-docker-compose.jar

# Make port 8080 available to the world outside this container
EXPOSE 8080

# Run the jar file
ENTRYPOINT ["java", "-jar", "springboot-docker-compose.jar"]

Explanation of the Dockerfile:

  • FROM: Specifies the base image. We’re using OpenJDK 17.

  • WORKDIR: Sets /app as the working directory inside the container.

  • COPY: Copies the built Spring Boot JAR file into the container.

  • EXPOSE: Exposes port 8080 to allow communication with the app.

  • ENTRYPOINT: Specifies the command to run when the container starts.

Step 3: Build the Docker Image

Run the following command in your project directory to build the Docker image:

docker build -t springboot-docker-compose .

This command will build an image and tag it as springboot-docker-compose. You should see something like:

[+] Building 38.0s (8/8) FINISHED docker:default
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 508B 0.0s
=> [internal] load metadata for docker.io/library/openjdk:17-jdk-alpine 3.2s
=> [1/3] FROM docker.io/library/openjdk:17-jdk-alpine@sha256:4b6abae565492dbe9e7a894137c966a7485154238902f2f25e9dbd9784383d81 34.0s
=> => resolve docker.io/library/openjdk:17-jdk-alpine@sha256:4b6abae565492dbe9e7a894137c966a7485154238902f2f25e9dbd9784383d81 0.0s
=> => sha256:4b6abae565492dbe9e7a894137c966a7485154238902f2f25e9dbd9784383d81 319B / 319B 0.0s
=> => sha256:a996cdcc040704ec6badaf5fecf1e144c096e00231a29188596c784bcf858d05 951B / 951B 0.0s
=> => sha256:264c9bdce361556ba6e685e401662648358980c01151c3d977f0fdf77f7c26ab 3.48kB / 3.48kB 0.0s
=> => sha256:5843afab387455b37944e709ee8c78d7520df80f8d01cf7f861aae63beeddb6b 2.81MB / 2.81MB 0.5s
=> => sha256:53c9466125e464fed5626bde7b7a0f91aab09905f0a07e9ad4e930ae72e0fc63 928.44kB / 928.44kB 1.3s
=> => sha256:d8d715783b80cab158f5bf9726bcada5265c1624b64ca2bb46f42f94998d4662 186.80MB / 186.80MB 31.4s
=> => extracting sha256:5843afab387455b37944e709ee8c78d7520df80f8d01cf7f861aae63beeddb6b 0.2s
=> => extracting sha256:53c9466125e464fed5626bde7b7a0f91aab09905f0a07e9ad4e930ae72e0fc63 0.1s
=> => extracting sha256:d8d715783b80cab158f5bf9726bcada5265c1624b64ca2bb46f42f94998d4662 2.3s
=> [internal] load build context 1.3s
=> => transferring context: 47.50MB 1.2s
=> [2/3] WORKDIR /app 0.4s
=> [3/3] COPY target/springboot-docker-compose-0.0.1-SNAPSHOT.jar /app/springboot-docker-compose.jar 0.1s
=> exporting to image 0.2s
=> => exporting layers 0.2s
=> => writing image sha256:60fbd89cb3f74ca4e7b40f2d776c47287dba147983f6377b8ac3e93827fa6468 0.0s
=> => naming to docker.io/library/springboot-docker-compose 0.0s

View build details: docker-desktop://dashboard/build/default/default/ibnrwfr22cun5rzqard65flb6

Step 4: Run the Docker Container

Now, let’s run the container:

docker run -p 8080:8080 springboot-docker-compose

This maps the container’s port 8080 to your local machine’s port 8080. Visit http://localhost:8080 in your browser, and your Spring Boot application should be running!

Introducing Docker Compose

Let’s say your Spring Boot app needs a MySQL database. Running both the Spring Boot app and MySQL in separate containers can get tedious. Here’s where Docker Compose shines!

Step 5: Create docker-compose.yml

In your project directory, create a file called docker-compose.yml:

version: '3.8'
services:
  app:
    image: springboot-docker-compose
    build:
      context: .
    ports:
      - "8080:8080"
    depends_on:
      - db
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: mydb
      MYSQL_USER: user
      MYSQL_PASSWORD: password
    ports:
      - "3306:3306"
    volumes:
      - db_data:/var/lib/mysql

volumes:
  db_data:

Explanation:

We define two services: app (our Spring Boot app) and db (MySQL).

  • The app service builds from our Dockerfile and depends on the db service.

  • The db service runs a MySQL container with environment variables to set up the database.

  • We use a volume (db_data) to persist MySQL data.

Step 6: Run Docker Compose

Run the following command to start both containers:

docker compose up

Docker Compose will start the MySQL and Spring Boot containers. You can now connect your Spring Boot app to the MySQL database at localhost:3306.

Conclusion

Docker allows developers to simplify their development environments, ensuring consistent behavior across platforms. Docker Compose adds another layer by managing complex, multi-container setups with ease. With Docker in your toolbox, you can now develop, test, and deploy your Spring Boot applications in a faster, more reliable way!

That’s all for the moment! We’ll keep bringing more fascinating topics that can help everyone grow and improve. Thank you 🙏 for taking the time to read this post. I appreciate your engagement with my content. Stay tuned for more updates. 🔖

Source Code: Follow this link to visit the GitHub Repository.

More from this blog

T

thegeekplanets

21 posts