How to setup Docker compose for a basic Spring Boot Application

    How to setup Docker compose for a basic Spring Boot Application

    Learn how to containerize a Spring Boot application and its dependencies using Docker Compose. This blog covers creating a simple Spring Boot project with PostgreSQL, writing a Dockerfile for containerization, configuring docker-compose.yml for multi-container orchestration

    default profile

    Santosh Mane

    December 14, 2024

    6 min read

    Introduction#

    Docker Compose simplifies running multi-container Docker applications by managing services through a single configuration file. For a Spring Boot application, it helps containerize the application and its dependencies, like a database, for seamless deployment. This guide walks you through setting up Docker Compose for a basic Spring Boot application.

    Steps#

    Step-1 Create Simple Spring boot project#

    1. Visit https://start.spring.io/ and create the basic spring boot project, we will create a basic messaging project which will store text messages in postgreSQL database
    1. Add the dependencies as shown in above figure and generate the zip folder, after generating the zip folder extract the folder and open the project in Intellij or any other editor you prefer.

    Step-2 Project Structure#

    Create the Controller Endpoints, Service and Repository for the project, we will be creating simple messaging app which will allow us to create message and store them in postgres DB and fetch all the messages.

    1. Entity class
    @Entity @Data @AllArgsConstructor @NoArgsConstructor public class Message { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String title; }
    1. Repository
    @Repository public interface MessagingRepository extends JpaRepository<Message,Long> { }
    1. Service
    @Service @RequiredArgsConstructor public class MessagingService { private final MessagingRepository messagingRepository; public Message createMessage(Message message){ return messagingRepository.save(message); } public List<Message> getMessages(){ return messagingRepository.findAll(); } }
    1. Controller
    @RestController @RequestMapping("/messages") @RequiredArgsConstructor public class MessagingController { private final MessagingService messagingService; @PostMapping("/createMessage") ResponseEntity<Message> createMessage(@RequestBody Message message){ System.out.println(message.getId()); return ResponseEntity.ok(messagingService.createMessage(message)); } @GetMapping ResponseEntity<List<Message>> getMessages(){ return ResponseEntity.ok(messagingService.getMessages()); } }

    Application properties

    Configure database related configuration in application.properties file

    spring.application.name=messaging server.port=8080 spring.datasource.url=jdbc:postgresql://messaging-db:5432/messaging_db spring.datasource.username=postgres spring.datasource.password=postgres spring.jpa.hibernate.ddl-auto=create-drop

    Note:- Here messaging-db is the container name in which the postgres is running.

    Step-3 Docker Installation#

    1. Visit https://docs.docker.com/desktop/setup/install/windows-install/ to install docker desktop on windows.
    2. Visit https://docs.docker.com/desktop/setup/install/mac-install/ to install docker on mac system.
    3. After installing docker on your machine start docker engine.

    Step-4 Creating Docker file#

    1. We have to create a Dockerfile and place it at a root directory of our project, with the help of this docker file we can build the docker image of our project.
    2. Dockerfile
    FROM maven:3.9.4-eclipse-temurin-21-alpine WORKDIR /app COPY .mvn/ .mvn COPY mvnw pom.xml ./ RUN ./mvnw dependency:go-offline COPY src ./src CMD ["./mvnw", "spring-boot:run"]
    1. Understanding the Dockerfile

    This Dockerfile creates a Docker image for the Spring Boot application. It uses Maven as the build tool and ensures all dependencies are resolved before running the application. Let’s explore each line: - 

    1. Base Image:
      • Uses the official Maven Docker image (maven:3.9.4-eclipse-temurin-21-alpine) as the foundation.
      • This image is lightweight (alpine) and includes:
      • Maven version 3.9.4 for building the application.
      • Java Development Kit (JDK) version 21 (Temurin), compatible with Spring Boot.
    1. Setting the Working Directory - WORKDIR /app
      • Sets the working directory for the image to /app.
      • All subsequent commands will run inside this directory.
    2. Copy Maven Wrapper Files
          COPY .mvn/ .mvn
          COPY mvnw pom.xml ./
      • .mvn/ and mvnw: The Maven Wrapper files allow the project to use a specific Maven version without requiring Maven pre-installed on the host.
      • pom.xml: The Maven Project Object Model file containing dependency and build configurations.
    3. Download Dependencies - RUN ./mvnw dependency:go-offline
      • Downloads all project dependencies and plugins required for the build.
      • Ensures the container can build the application without accessing the internet later, improving speed and reliability.
    4. Copy Application Source Code - COPY src ./src
      • Copies the entire src directory from the local machine into the /app/src directory inside the container.
    5. Start the Application - CMD ["./mvnw", "spring-boot:run"]
      1. CMD - Defines the command to run the Spring Boot application using the Maven Wrapper.
      2. spring-boot:run : Launches the Spring Boot application directly from the source, ideal for development environments.

    Step-5 Creating Docker-compose file for your spring boot project#

    1. Create docker-compose.yml file and place it at the root dir of your project
    2. docker-compose.yml file
    version: '3.8' services: messaging-app: build: context: . dockerfile: Dockerfile ports: - "8080:8080" depends_on: - messaging-db networks: - messaging-network environment: SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/messaging_db SPRING_DATASOURCE_USERNAME: postgres SPRING_DATASOURCE_PASSWORD: postgres messaging-db: image: postgres:15 container_name: postgres_db environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_DB: messaging_db ports: - "5432:5432" volumes: - db_data:/var/lib/postgresql/data networks: - messaging-network volumes: db_data: networks: messaging-network:

    Before moving forward let's understand the docker-compose file#

    Breaking Down the docker-compose.yml File for Messaging App. This docker-compose.yml file defines a multi-container setup for the Messaging App, which includes a Spring Boot application (messaging-app) and a PostgreSQL database (messaging-db). Let's walk through each section to understand its purpose.

    1. Version version: '3.8’ - Specifies the Docker Compose file format version. Version 3.8 is the latest supported version for modern Docker setups, ensuring compatibility with features like custom networks.
    2. Services: The services section defines the containers that make up the application.
    • build:
      • Specifies the build context (. refers to the current directory) and the Dockerfile used to containerize the application.
    • ports:
      • Maps port 8080 on the host machine to port 8080 in the container, making the application accessible locally at http://localhost:8080.
    • depends_on:
      • Ensures the messaging-db service (PostgreSQL database) starts before the messaging-app service.
    • networks:
      • Connects the messaging-app container to the messaging-network for isolated communication between services.
    • environment:
      • Overrides database configuration in the Spring Boot application:
        • SPRING_DATASOURCE_URL: Points to the messaging-db service at messaging_db, the alias provided by the Docker Compose network.
        • SPRING_DATASOURCE_USERNAME and SPRING_DATASOURCE_PASSWORD : Credentials for the PostgreSQL database.
    • image:
      • Specifies the PostgreSQL Docker image version 15.
    • container_name:
      • Assigns the container a fixed name (postgres_db) for easier identification in commands and logs.
    • environment:
      • Configures the PostgreSQL instance:
        • POSTGRES_USER: Database username.
        • POSTGRES_PASSWORD: Database password.
        • POSTGRES_DB: Creates a default database named messaging_db.
    • ports:
      • Maps port 5432 on the host to port 5432 inside the container, enabling local access to the database.
    • volumes:
      • Defines a persistent volume (db_data) to store PostgreSQL data, ensuring data is not lost when containers are restarted.
    • networks:
      • Connects the database to the same messaging-network for seamless communication with the application.
    1. Volumes
      • Creates a named volume (db_data) to persist PostgreSQL data outside the container lifecycle.
      • Stored data survives container restarts or removal, making it ideal for production setups.
    2. Networks
      • Defines a custom Docker network (messaging-network) for the messaging-app and messaging-db services.
      • Ensures isolated and secure communication between the containers, preventing interference from other Docker networks.

    Step-6 Run Docker Compose#

    Run command

    1. Open a terminal in your project directory.
    2. Run the following command to build and start the containers:
    docker-compose up --build

    Verify:

    • Your Spring Boot app should be accessible at http://localhost:8080.
    • PostgreSQL is running at localhost:5432.

    Step-7 Testing#

    1. Test your endpoints using tools like Postman or CURL.
    2.  logChecks to ensure the services are communicating:
    docker-compose logs messaging-app docker-compose logs messaging-db

    Step-8 Clean Up#

    To stop and remove containers, use:

    docker-compose down

    Conclusion#

    Using Docker Compose, you can streamline development by creating isolated environments for your Spring Boot application and its dependencies. This setup ensures consistency, scalability, and ease of deployment.

    Spring Boot
    Spring
    Docker Compose
    Docker

    More articles