Generate a docker-compose.yml with mock services in Python

Build a docker-compose.yml string from a Python dict of service names and images, then write it to a file.

Easy Python 3.9+ Aug 9, 2026 Production deployment patterns 17 views 0 copies

Requires third-party packages — install first
pip install pyyaml

Python code

27 lines
Python 3.9+
import yaml
from pathlib import Path

def generate_mock_compose(services: dict) -> str:
    compose = {
        "version": "3.9",
        "services": {}
    }
    
    for name, image in services.items():
        compose["services"][name] = {
            "image": image,
            "container_name": f"mock-{name}",
            "restart": "unless-stopped"
        }
    
    return yaml.dump(compose, default_flow_style=False, sort_keys=False)

if __name__ == "__main__":
    services = {
        "web": "nginx:latest",
        "db": "postgres:16",
        "cache": "redis:7"
    }
    output = generate_mock_compose(services)
    print(output)
    Path("docker-compose.yml").write_text(output)

Output

stdout
version: '3.9'
services:
  web:
    image: nginx:latest
    container_name: mock-web
    restart: unless-stopped
  db:
    image: postgres:16
    container_name: mock-db
    restart: unless-stopped
  cache:
    image: redis:7
    container_name: mock-cache
    restart: unless-stopped

How it works

The function takes a simple dict mapping service names to Docker images and builds a nested dict that mirrors the docker-compose.yml structure. yaml.dump converts that dict into YAML text with default_flow_style=False to keep it block-style and human-readable. Setting sort_keys=False preserves the insertion order so services appear in the same order as in the input. The Path.write_text call saves the YAML to disk, and the file is ready to use with docker compose up.

Common mistakes

  • Forgetting to quote the version number in the output — YAML 1.1 parses 3.9 as a float; use single quotes as shown.
  • Overwriting an existing docker-compose.yml without a backup or check — consider adding a `Path.exists()` guard.
  • Hardcoding the compose version when modern Docker supports `version` as optional and deprecated.
  • Assuming `yaml` is installed — it's not in the standard library; you must `pip install pyyaml`.

Variations

  1. Use `yaml.safe_dump` instead of `yaml.dump` for safer output when handling untrusted containers.
  2. Add environment variables or ports to the service dict for a richer mock setup.

Real-world use cases

  • Generating throwaway local environments for integration tests where real services can be replaced with mocks.
  • Scripting the creation of a compose file from a configuration file or CI variables for reproducible deployments.
  • Producing a template compose file that developers can edit before spinning up a group of related services.

Sponsored

Run locally

This sample needs third-party packages, so it cannot run in the browser IDE. Copy the code above, install the packages shown at the top, then run it in your own Python environment.

More from Production deployment patterns

Related tutorials and quizzes for this topic.