on
Compose smarter: use profiles + Buildx Bake to speed local microservices development
When you’re running half a dozen microservices on your laptop, the experience can feel like trying to rehearse a band in a closet: everything gets loud, resources spike, and the small tweaks you want to hear take forever. Docker Compose gives you two practical tools to simplify that rehearsal: service profiles (to run only the tracks you need) and Buildx Bake (to separate fast local builds from heavier production builds). Together they let you iterate quickly locally while keeping production builds robust and repeatable. (docs.docker.com)
Why separate dev runtime from production builds?
Local development benefits from speed and minimal friction: short rebuilds, a small set of services, hot-reload-friendly images. Production builds, on the other hand, often require multi-platform images, attestations, SBOMs, or different Dockerfile stages. If you try to fold everything into a single Compose workflow, you slow down the thing you care about most: fast iteration.
Docker’s recommended pattern is to keep Compose focused on local runtime and to use Buildx Bake (BuildKit) when you need production-grade build features. That way you reuse the same service definitions but avoid paying the time cost during daily development. (docs.docker.com)
Service profiles: turn your stack into playlists
Profiles let you tag services in your Compose file and only start the groups you need. Think of profiles like playlists: one for “core app”, one for “debug tools”, another for “integration tests”.
Example docker-compose.yml snippet:
services:
api:
build: ./api
ports: ["8000:8000"]
db:
image: postgres:15
environment:
POSTGRES_PASSWORD: secret
metrics:
image: prom/prometheus
profiles: ["monitoring"]
admin:
image: phpmyadmin
depends_on: ["db"]
profiles: ["debug"]
- Running the core stack: docker compose up will start api + db (services without profiles).
- Enabling the monitoring playlist: docker compose –profile monitoring up starts metrics in addition to core services.
This keeps your laptop lighter by default while letting you opt in to extras when you need them. (docs.docker.com)
Tip: you can set COMPOSE_PROFILES to enable profiles from the environment if you prefer not to pass flags on every command. (docs.docker.com)
Bake with Buildx: production-ready image builds without slowing local iterations
Bake (docker buildx bake) reads build config from your Compose file and (optionally) a docker-bake.hcl to create a declarative build plan. You can:
- Keep your Compose build stages optimized for local development (fast dev stage), and use Bake to target the final production stage.
- Add multi-platform targets, attestations, and SBOMs to Bake without cluttering your Compose file.
- Build groups of images in parallel and control caching behavior separately from your dev workflow. (docs.docker.com)
Example docker-bake.hcl:
group "default" {
targets = ["api", "worker"]
}
target "api" {
context = "./api"
dockerfile = "Dockerfile"
target = "final" # build production stage
tags = ["example/api:stable"]
}
target "_common" {
platforms = ["linux/amd64", "linux/arm64"]
attest = ["type=sbom"]
}
target "worker" {
inherits = ["_common"]
context = "./worker"
dockerfile = "Dockerfile"
tags = ["example/worker:stable"]
}
Then run: docker buildx bake — this handles production-oriented options while leaving docker compose up fast for day-to-day work. (docs.docker.com)
The Compose project also added explicit support for using Buildx Bake with Compose, so this pattern is supported and maintained in the official tooling. (Bake integration was highlighted in Compose release notes.) (docs.docker.top)
Putting the two together: a simple workflow
- During day-to-day development:
- Use compact Compose files with profiles for optional services.
- Use dev-oriented Dockerfile stages (e.g., target: dev) or simple images for faster builds.
- Example: docker compose –profile debug up –build
- For release or CI:
- Use docker buildx bake (with docker-bake.hcl) to produce production-grade images (multi-platform, SBOMs, different stages).
- Bake reads and extends the Compose build definitions so you don’t repeat contexts or Dockerfile locations. (docs.docker.com)
You can also control build parallelism (to speed up CI or local Bake runs) using Compose/Buildx parallel options. Compose supports a –parallel flag and related environment variables to tune concurrency when pulling or building. (docs.docker.com)
Practical tips (mixing music metaphors with a little pragmatism)
- Keep core services profile-free. Those are your rhythm section — always present. Put optional dev tools (profilers, admin UIs, mocks) in profiles. (docs.docker.com)
- Use a small dev stage in your Dockerfile that copies just what you need for iteration (live reload files, dev deps). Let Bake target the fuller final stage for production. (docs.docker.com)
- Cache aggressively during local builds (BuildKit cache mounts) but keep expensive features (multi-platform, attestations) in Bake so your laptop isn’t doing cross-compile work you don’t need. (docs.docker.com)
- If you have CI that mirrors the local Compose layout, pipe the same docker-bake.hcl into CI for parity between dev and release images.
Conclusion
Profiles and Buildx Bake together let you treat your microservice stack like both a rehearsal space and a recording studio: light and nimble while you iterate, and fully featured when you publish. The Compose tooling explicitly supports these patterns, so you get the convenience of Compose for local development and the power of BuildKit/Buildx for production builds—without turning everyday work into a long build session. (docs.docker.com)