7 Running multi-container apps with Docker Compose
Modern applications are rarely single processes; they’re composed of multiple components that must be packaged, connected, and configured consistently. Docker Compose solves this by providing a simple YAML format to declare the desired state of a multi-container app (services, networks, volumes, and secrets) and a command-line tool that realizes that state by creating the required Docker resources. Instead of stringing together fragile docker run commands, you capture images, ports, and network membership in one file that lives alongside your code, making app setup repeatable and self-documenting across machines and environments.
With Compose, you define each component as a service and can express dependencies, publish ports, and plug services into shared networks. Bringing an app up or down is a single command, and Compose aggregates logs and supports detached mode so containers run in the background. You can scale stateless services with a flag, and manage the application as a whole while still using the Docker CLI for individual containers. Importantly, Compose is a client-side tool: it applies what’s in the YAML to one Docker host but doesn’t continuously reconcile state. Runtime changes not recorded in the file (like an ad hoc scale-up) are lost when you recreate the app, and Compose won’t restart failed containers unless you run it again.
Compose also handles how containers talk and how they’re configured. Docker’s virtual networks and built-in DNS let services discover each other by name, and when a service is scaled, DNS returns multiple IPs to provide simple load distribution; changing containers get new IPs, but names stay stable. Configuration is externalized through environment variables and secrets, letting the same image run differently per environment—for example, switching a web app from an embedded SQLite store to a Postgres service by declaring both services, publishing their ports, and injecting connection details as a secret. The result is a consistent, portable workflow ideal for development, testing, and straightforward production deployments, while recognizing that high availability and continuous reconciliation are responsibilities of full orchestration platforms, not Compose.
The architecture of a simple Compose application with one service and one network
Starting an app using Docker Compose, which creates Docker resources
A more complex Compose file that specifies three services connected to the same network
Starting a multi-container app with dependencies specified using Docker Compose
Scaling up an application component and checking its logs with Docker Compose
Stopping and starting multi-container apps with Docker Compose
Removing and re-creating an app resets it to the state in the Docker Compose file.
Scaling a service with Docker Compose and performing DNS lookups
Services scale with multiple containers—every container’s IP address is returned in a lookup.
Running a new application with Docker Compose and listing its containers
Running the to-do app in containers with a Postgres database and querying the data
Where you use Docker Compose in the application lifecycle from development to production
Lab
Docker Compose has some useful features that add reliability to running your app. In this lab, I’d like you to create a Compose definition to run the to-do web app more reliably in a test environment so that:
- The application containers will restart if the machine reboots, or if the Docker engine restarts.
- The database container will use a bind mount to store files, so you can bring the app down and up again but retain your data.
- The web application should listen on standard port 80 for test.
Just one hint for this one:
- You can find the Docker Compose file specification in Docker’s reference documentation at https://docs.docker.com/compose/compose-file. That defines all the settings you can capture in Compose.
My sample solution is on the book’s GitHub repository, as always. Hopefully, this one isn’t too complex, so you won’t need it: https://github.com/sixeyed/diamol/blob/2e/ch07/lab/README.md.
Learn Docker in a Month of Lunches, Second Edition ebook for free