Running docker-compose from python
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
Python is often used to drive local development environments, test suites, and deployment helpers. When that workflow needs containers, the simplest approach is usually to call Docker Compose from Python rather than trying to reimplement Compose behavior through the Docker API.
Prefer the CLI Over Rebuilding Compose Logic
Even though the old standalone command was named docker-compose, current Docker installations typically expose Compose as docker compose. From Python, that difference only changes the command arguments you pass to subprocess.
For most automation tasks, the CLI is the right abstraction. Compose already knows how to read compose.yaml, resolve environment files, build images, and start dependent services in the correct order. The Docker SDK for Python is useful for container-level operations, but it does not replace the full Compose workflow cleanly.
Running Compose With subprocess
Use subprocess.run when you want a simple call that either succeeds or fails.
There are a few details worth keeping:
- Pass the command as a list instead of one shell string.
- Set
cwdto the directory that contains the Compose file. - Capture output so your Python code can show a useful error message.
- Avoid
shell=Trueunless you truly need shell features.
If your project uses a non-default file name, add -f and the file path to the argument list.
Streaming Logs and Waiting for Readiness
Sometimes you do not just need to start containers; you need to watch the output until a service is ready. In that case, use subprocess.Popen so you can process lines as they arrive.
This pattern is common in integration tests. Start the stack with up -d, then follow logs until a known readiness message appears. If the service never becomes healthy, your Python code can time out and tear the stack down.
Cleaning Up Reliably
Compose automation should always include cleanup, especially in tests and CI jobs. The safest pattern is to use try and finally.
Using --volumes is helpful when you want each test run to start from a clean state. In a developer workflow, you may prefer plain down so named volumes persist.
Common Pitfalls
The biggest mistake is assuming the Docker SDK can directly do everything Compose does. It can manage individual containers, networks, and images, but it will not automatically interpret your Compose project the same way the CLI does.
Another common issue is hard-coding docker-compose when the machine only has the plugin form, or hard-coding docker compose on an older machine that still uses the standalone binary. A small detection helper avoids that portability problem.
Developers also get tripped up by running from the wrong working directory. Compose resolves relative paths, environment files, and default project names from the current directory, so an incorrect cwd can make a working command fail mysteriously.
Finally, do not ignore exit codes. If you launch Compose and continue as though it succeeded, your Python script will usually fail later with much less useful diagnostics.
Summary
- Use Python to invoke the Compose CLI, not to reproduce Compose behavior manually.
- Prefer
subprocess.runfor one-shot commands andsubprocess.Popenwhen you need streaming output. - Pass arguments as a list, set the correct
cwd, and capture or stream logs intentionally. - Detect whether the system provides
docker composeordocker-compose. - Always clean up containers after tests or temporary automation runs.
Related reading
- Running docker on Ubuntu mounted host volume is not writable from container
- Running Kafka cluster in Docker containers?
- Running multiple projects using docker which each runs with docker-compose
- running nvidia-docker on Windows 10 WSL2
- Running multiple tensorflow sessions concurrently
- Running Python on Windows for Node.js dependencies
- SASL authentication in docker zookeeper and kafka
- Scalable spring batch job on kubernetes

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.