Docker Compose Support in Spring Boot 3.1

Engineering | Moritz Halbritter | June 21, 2023 | ...

Docker Compose support in Spring Boot 3.1 builds on top of the ConnectionDetails abstraction, which we've featured in a separate blog post. If you haven't already read it, please do so before reading this post.

Docker Compose "is a tool for defining and running multi-container Docker applications". A Docker Compose configuration file, usually named docker-compose.yaml or compose.yaml, allows you to define services. Such services must have a name and a Docker image. Optionally you can also define environment variables, exposed ports, labels, how services relate to one another, and so on.

Here's a typical example of a simple Docker Compose file:

services:
  database:
    image: 'postgres:15.2'
    ports:
    - '5432'
    environment:
    - 'POSTGRES_USER=myuser'
    - 'POSTGRES_DB=mydatabase'
    - 'POSTGRES_PASSWORD=secret'

It defines one service named database, which uses the postgres:15.2 Docker image. It exposes the container port 5432 (which is the default PostgreSQL port), and Docker will choose a random host port on startup. Additionally, it defines some environment variables which configure the user, password, and database name.

If you run docker compose up in the directory where this file resides, Docker Compose will first check if this service is already running. If not, it will start a new container using the postgres:15.2 image and configure it.

You can now run docker compose ps and see that the container has been started:

$ docker compose ps
NAME                             IMAGE               COMMAND                  SERVICE             CREATED             STATUS              PORTS
docker-compose-test-database-1   postgres:15.2       "docker-entrypoint.s…"   database            7 seconds ago       Up 6 seconds        0.0.0.0:32768->5432/tcp, :::32768->5432/tcp

To develop against that service in a pre-Spring Boot 3.1 application, you have to put some configuration properties in place, maybe in some kind of "developer" profile:

spring.datasource.url=jdbc:postgresql://localhost:32768/mydatabase
spring.datasource.username=myuser
spring.datasource.password=secret

This configures Spring Boot to use the PostgreSQL database running inside the Docker container (connecting on the host port 32768).

When you're done using the service, you'll typically run docker compose down to stop and destroy the containers. But when you start them again, you'll see that the dynamic port has changed:

$ docker compose ps
NAME                             IMAGE               COMMAND                  SERVICE             CREATED             STATUS              PORTS
docker-compose-test-database-1   postgres:15.2       "docker-entrypoint.s…"   database            4 minutes ago       Up 1 second         0.0.0.0:32769->5432/tcp, :::32769->5432/tcp

Oh no, that means you'll now have to update the application configuration!

Luckily, Docker Compose has a solution for that. Don't use random ports, use a fixed host port:

services:
  database:
    image: 'postgres:15.2'
    ports:
      - '15432:5432'
    environment:
      - 'POSTGRES_USER=myuser'
      - 'POSTGRES_DB=mydatabase'
      - 'POSTGRES_PASSWORD=secret'

Now, every time you start the container, it's reachable on localhost:15432.

This works, but there's a different problem. If you're developing multiple applications where each application has their own database (which is quite common in microservice architectures), you have to remember to use different host ports. If you don't, some docker compose up commands fail because the port is already in use.

And now the good news. With Spring Boot 3.1, this gets a lot easier for you. You can continue to use random host ports but you don't have to specify configuration properties and you don't have to duplicate usernames, passwords, and so on in multiple places. You also don't have to remember to run docker compose up before starting the application.

Spring Boot 3.1 will detect that there's a Docker Compose file present, and will run docker compose up for you before connecting to the services. If the services are already running, it will detect that, too, and will use them. It will also run docker compose stop when the application shuts down - gone are the days of lingering Docker containers eating your precious memory.

The images started by Docker Compose are automatically detected and used to create ConnectionDetails beans pointing to the services. That means you don't have to put properties in your configuration, you don't have to remember how to construct PostgreSQL JDBC URLs, and so on.

With Spring Boot 3.1, all you need to do is to provide the compose.yaml file and let Spring Boot figure out the rest. It just works!

At the time of writing, we support the following Docker images:

Want to try this yourself? We've prepared some documentation to get you started.

We have also added support for Docker Compose to start.spring.io to get you started even faster! For example, if you generate a project with "Docker Compose support" and "PostgreSQL driver" dependencies, you'll get a sensible compose.yaml for free! Isn't that absolutely awesome?!

"Okay, okay", I hear you say, "but what about my custom Redis image we use at our company?". We have you covered: you can build your own image, put a label on it and Spring Boot will pretend that it's the official image. Just make sure that you use the same environment variable names as the official image.

We also support ignoring services, Docker Compose files with unusual names, and Docker Compose profiles.

We really hope you like the new Docker Compose features! If you want to see more services supported, or have other ideas how to improve things, please get in touch.

Get the Spring newsletter

Thank you for your interest. Someone will get back to you shortly.

Get ahead

VMware offers training and certification to turbo-charge your progress.

Learn more

Get support

Tanzu Spring Runtime offers support and binaries for OpenJDK™, Spring, and Apache Tomcat® in one simple subscription.

Learn more

Upcoming events

Check out all the upcoming events in the Spring community.

View all