Docker Tip #94: Docker Compose v2 and Profiles Are the Best Thing Ever
I switched to v2 because it's faster and profiles let you easily start specific services in different environments.
Prefer video? Here’s a recorded version of this tip on YouTube which demonstrates using profiles and more.
Docker Compose v2 was marked generally available in April 2022, its timeline is:
- October 2022: v2 will be on by default and you can opt-out of it in Docker Desktop
- April 2023: v2 will be the only option with Docker Desktop
The 3 biggest reasons on why I’ve switched to it are:
- Containers start and stop faster than Docker Compose v1
- Docker Compose profiles support with seamless optional
depends_onto make it easy to control running specific containers in different environments (it’s a pure upgrade to the override file pattern)
- v2 is a Docker plugin written in Go, there’s no need for a Python environment anymore (btw even the curl version of Docker Compose v1 uses PyInstaller to bundle it up)
I’ve updated all of my example Docker web apps to use Docker Compose v2 with profiles and also updated my Ansible role to install Docker Compose v2 by default. It works nicely on native Linux without Docker Desktop since it’s just a system package to install.
With profiles imagine having a
docker-compose.yml such as this (simplified to demo profiles):
services: postgres: profiles: ["postgres"] redis: profiles: ["redis"] web: profiles: ["web"] depends_on: ["postgres", "redis"] worker: profiles: ["worker"] depends_on: ["postgres", "redis"] assets: profiles: ["assets"]
In development you can set this environment variable in an
.env file to start everything:
In production you can set this instead:
You can also use the
docker compose --profile web,worker up flag instead of an environment variable but I prefer using the environment variable approach to avoid needing to run custom commands on different servers.
The above expects your assets would be built beforehand in production instead of running various asset watcher containers like
tailwind in development.
The above also expects you may want to run managed versions of Postgres and Redis on your cloud provider of choice, but you don’t have to do this. Even with
depends_on defined on your
worker services it doesn’t matter. Docker Compose v2 is smart enough to know to ignore the dependent services because you didn’t specify the
redis profiles to run.
You could even choose to run your
worker on separate servers by only specifying each one individually such as
export COMPOSE_PROFILES=web and
export COMPOSE_PROFILES=worker on each server.
Profiles are very flexible, they’re great! I switched over to this combo for both development and production in August 2022.