157 lines
3.8 KiB
Markdown
157 lines
3.8 KiB
Markdown
---
|
|
title: Docker Compose Patterns
|
|
description: Reusable patterns for structuring Docker Compose applications in homelab and development environments
|
|
tags:
|
|
- containers
|
|
- docker
|
|
- compose
|
|
category: containers
|
|
created: 2026-03-14
|
|
updated: 2026-03-14
|
|
---
|
|
|
|
# Docker Compose Patterns
|
|
|
|
## Introduction
|
|
|
|
Docker Compose defines multi-container applications in a single declarative file. It is a good fit for homelab stacks, local development, and small self-hosted services that do not require a full orchestrator.
|
|
|
|
## Purpose
|
|
|
|
Compose helps when you need:
|
|
|
|
- Repeatable service definitions
|
|
- Shared networks and volumes for a stack
|
|
- Environment-specific overrides
|
|
- A clear deployment artifact that can live in Git
|
|
|
|
## Architecture Overview
|
|
|
|
A Compose application usually includes:
|
|
|
|
- One or more services
|
|
- One or more shared networks
|
|
- Persistent volumes
|
|
- Environment variables and mounted configuration
|
|
- Optional health checks and startup dependencies
|
|
|
|
## Step-by-Step Guide
|
|
|
|
### 1. Start with a minimal Compose file
|
|
|
|
```yaml
|
|
services:
|
|
app:
|
|
image: ghcr.io/example/app:1.2.3
|
|
ports:
|
|
- "8080:8080"
|
|
```
|
|
|
|
Start it:
|
|
|
|
```bash
|
|
docker compose up -d
|
|
docker compose ps
|
|
```
|
|
|
|
### 2. Add persistent storage and configuration
|
|
|
|
```yaml
|
|
services:
|
|
app:
|
|
image: ghcr.io/example/app:1.2.3
|
|
ports:
|
|
- "8080:8080"
|
|
environment:
|
|
APP_BASE_URL: "https://app.example.com"
|
|
volumes:
|
|
- app-data:/var/lib/app
|
|
|
|
volumes:
|
|
app-data:
|
|
```
|
|
|
|
### 3. Add dependencies with health checks
|
|
|
|
```yaml
|
|
services:
|
|
db:
|
|
image: postgres:16
|
|
environment:
|
|
POSTGRES_DB: app
|
|
POSTGRES_USER: app
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U app"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
volumes:
|
|
- db-data:/var/lib/postgresql/data
|
|
|
|
app:
|
|
image: ghcr.io/example/app:1.2.3
|
|
depends_on:
|
|
db:
|
|
condition: service_healthy
|
|
environment:
|
|
DATABASE_URL: postgres://app:${POSTGRES_PASSWORD}@db:5432/app
|
|
ports:
|
|
- "8080:8080"
|
|
|
|
volumes:
|
|
db-data:
|
|
```
|
|
|
|
## Common Patterns
|
|
|
|
### Use one project directory per stack
|
|
|
|
Keep the Compose file, `.env` example, and mounted config together in one directory.
|
|
|
|
### Use user-defined networks
|
|
|
|
Private internal services should communicate over Compose networks rather than the host network.
|
|
|
|
### Prefer explicit volumes
|
|
|
|
Named volumes are easier to back up and document than anonymous ones.
|
|
|
|
### Use profiles for optional services
|
|
|
|
Profiles are useful for dev-only services, one-shot migration jobs, or optional observability components.
|
|
|
|
## Troubleshooting Tips
|
|
|
|
### Services start in the wrong order
|
|
|
|
- Use health checks instead of only container start order
|
|
- Ensure the application retries database or dependency connections
|
|
|
|
### Configuration drift between hosts
|
|
|
|
- Commit the Compose file to Git
|
|
- Keep secrets out of the file and inject them separately
|
|
- Avoid host-specific bind mount paths when portability matters
|
|
|
|
### Containers cannot resolve each other
|
|
|
|
- Check that the services share the same Compose network
|
|
- Use the service name as the hostname
|
|
- Verify the application is not hard-coded to `localhost`
|
|
|
|
## Best Practices
|
|
|
|
- Omit the deprecated top-level `version` field in new Compose files
|
|
- Keep secrets outside the Compose YAML when possible
|
|
- Pin images to intentional versions
|
|
- Use health checks for stateful dependencies
|
|
- Treat Compose as deployment code and review changes like application code
|
|
|
|
## References
|
|
|
|
- [Docker: Compose file reference](https://docs.docker.com/reference/compose-file/)
|
|
- [Docker: Compose application model](https://docs.docker.com/compose/intro/compose-application-model/)
|
|
- [Docker: Control startup and shutdown order in Compose](https://docs.docker.com/compose/how-tos/startup-order/)
|
|
- [Compose Specification](https://compose-spec.io/)
|