VMware offers training and certification to turbo-charge your progress.Learn more
Docker Compose support in Spring Boot 3.1 builds on top of the
ConnectionDetailsabstraction, 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
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
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
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 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.