· Jose Antonio López  · 5 min read

Setting Up a Spring Boot Project for Development

How to set up a Spring Boot project with docker-compose, PostgreSQL, and Spring Boot Developer tools.

How to set up a Spring Boot project with docker-compose, PostgreSQL, and Spring Boot Developer tools.

Objective

Explain how to set up a Spring Boot 3.3.5 project that uses docker-compose, PostgreSQL, and Spring Boot Developer tools.

Why am I writing this article?

Often, information is scattered and not in one place. Additionally, the information may be outdated or so convoluted that it discourages you from making improvements. My experience tells me that in the case of Spring, all the information is there but not in one place. Also, many times it is not clear what they are saying.

This article is a guide to have all the information in one place so you can set up your Spring Boot project in a development environment.

Prerequisites

To follow this article, you need to have installed:

RequirementDownload Link
JavaDownload Java
MavenDownload Maven
Docker DesktopDownload Docker Desktop
IntelliJ IDEA CommunityDownload IntelliJ IDEA Community

DotEnv

Purpose

Using a .env file serves to decouple the application’s configuration. It is used to have data that depends on the environment where the application is running. All this is sensitive to changes and should not be in the source code.

You can have as many files as environments you have:

  • .env for development
  • .env.test for testing
  • .env.staging for staging
  • .env.prod for production

If you deploy in a production environment, you must ensure that the environment variables are on the server, whether in-house or in the cloud.

The file names are arbitrary and it is up to the development team to decide what to call them. Don’t spend too much time debating. The important thing is that it is understood.

Configuration

Create a .env file in the root of the project. The file contains the environment variables that will be used in the project.

APPLICATION_NAME=crm

POSTGRES_DB=crm
POSTGRES_USER=postgres
POSTGRES_PASSWORD=password
POSTGRES_HOST=db
POSTGRES_PORT=5432

SPRING_DATASOURCE_URL=jdbc:postgresql://${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}
SPRING_DATASOURCE_USERNAME=${POSTGRES_USER}
SPRING_DATASOURCE_PASSWORD=${POSTGRES_PASSWORD}
SPRING_PORT=8080

Additional Information

When you encounter a syntax like ${POSTGRES_USER}, it is because a variable is being referenced. In this case, it refers to the POSTGRES_USER variable. The technical name for this syntax is interpolation.

Docker Compose

Purpose

Docker Compose is a tool that allows you to define and run Docker applications with more than one container. Docker Compose makes it easy to define configuration for containers. Instead of using docker run for each container and passing a bunch of parameters, you define a docker-compose.yml file and run docker-compose up.

Configuration

Add the following dependency:

pom.xml
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-docker-compose</artifactId>
  <scope>runtime</scope>
  <optional>true</optional>
</dependency>

Create a compose.yaml file in the root of the project. This file will contain the environment variables that will be used in the project. The environment variables are referenced with the syntax ${VARIABLE}.

It is the same strategy and syntax as in the .env file.

compose.yaml
services:
  app:
    build: .
    ports:
      - ${SPRING_PORT}:${SPRING_PORT}
    container_name: crm-app
    networks:
      - crm-network
    depends_on:
      db:
        condition: service_healthy
    environment:
      SPRING_DATASOURCE_URL: ${SPRING_DATASOURCE_URL}
      SPRING_DATASOURCE_USERNAME: ${SPRING_DATASOURCE_USERNAME}
      SPRING_DATASOURCE_PASSWORD: ${SPRING_DATASOURCE_PASSWORD}

  db:
    image: postgres:alpine
    ports:
      - ${POSTGRES_PORT}:${POSTGRES_PORT}
    container_name: postgres
    environment:
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    networks:
      - crm-network
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -U postgres']
      interval: 5s
      timeout: 20s
      retries: 3

networks:
  crm-network:
    driver: bridge

Additional Information

Options of docker-compose.yml

  • services: Defines the services that will run. In this case, two services will run: app and db.
  • networks: Defines the network to be used. In this case, the crm-network is used.
  • depends_on: Defines the dependency between services. The app service will wait for db to be healthy.
  • healthcheck: A command is launched to see if the database is ready.
  • network: The bridge type is the default and most common.

If you want to know more about driver types, you can visit the official documentation on drivers. If you want to know more about Docker Compose, you can visit the official Docker documentation.

How does it work?

Spring Boot has support for Docker Compose. When it detects a docker-compose.yml file in the root of the project, it starts the Docker containers using the docker-compose up command.

If it finds a container that is already running, Spring Boot does not restart it and skips it.

What I usually do is manually start the PostgreSQL container from IntelliJ and then start the Spring Boot application also from IntelliJ.

For more information on Docker Compose support in Spring Boot, you can visit the official Spring Boot documentation.

Developer Tools

Purpose

When you are programming locally and make changes, you have to stop the application, run the mvn clean install command, and restart the application. This is a repetitive and slow process.

Spring Boot Developer Tools allow the application to restart automatically when changes are detected in the source code.

Configuration

Add the following dependency:

pom.xml
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-devtools</artifactId>
  <version>3.4.1</version>
  <scope>runtime</scope>
  <optional>true</optional>
</dependency>

Additional Information

Developer Tools should not be loaded in production. They are only loaded in development environments. Therefore, the dependency has the scope set to runtime and optional. There are more advanced ways to control Developer Tools.

How does it work?

The restart of the Spring Boot application uses two classloaders. Classes that do not change, such as third-party libraries, are loaded in a base classloader. The classes you develop are loaded in a restart classloader. When the application restarts, the restart classloader is discarded and a new one is created. Application restarts will be much faster than “cold starts”.

If you want to know more, you can visit the official documentation.

Configuring IntelliJ

Purpose

Configure IntelliJ to run the application with Docker Compose and Developer Tools. If it works quickly for you, you can skip this configuration. In my case, it didn’t work the first time and it took almost 10 seconds to restart.

Configuration

If you want the IDE to save your changes and start the compilation automatically with any modification, you should go to:

  • Settings | Appearance & Behavior | System Settings | Save files if the IDE is idle for —> Set the value to 1 second

  • Settings | Build, Execution, Deployment | Compiler | Build project automatically —> Check the box

  • Settings | Advanced Settings | Allow auto-make to start even if developed application is currently running —> Check the box

  • Go to Help | Find Action | Registry. Set the value compiler.automake.postpone.when.idle.less.than=1000

Las fuentes usadas para este apartado son: The sources used for this section are:

Intellij Thread

Next Steps

Once the development environment is configured, the next step is to choose the right libraries for your project. You can consult the key dependencies in Spring Boot guide to know where to start.

  • Docker
  • Spring Boot
Share: