Use when: creating or modifying Docker Compose Jinja2 templates for Ansible roles, deciding between single-container and multi-container stack patterns, configuring ports, volumes, networks, or environment variables in docker_compose.yaml.j2 files.
Scanned 9/1/2026
Install to Claude Code
npx -y skills add jimmybish/homelab --skill docker-compose-templating --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Docker Compose Templating?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/jimmybish-docker-compose-templating)More formats (shields.io, HTML) on the badges page.
---
name: docker-compose-templating
description: 'Use when: creating or modifying Docker Compose Jinja2 templates for Ansible roles, deciding between single-container and multi-container stack patterns, configuring ports, volumes, networks, or environment variables in docker_compose.yaml.j2 files.'
---
# Docker Compose Templating
Patterns for generating `docker_compose.yaml.j2` Jinja2 templates used by Ansible roles to deploy Docker services.
## When to Use
- Creating a new `docker_compose.yaml.j2` template for an Ansible role
- Deciding between single-container vs multi-container stack layout
- Configuring port mappings, volumes, networks, or environment variables
- Adding a database or cache sidecar to an existing service
## Single-Container Services
```yaml
services:
<service>:
image: <image>:{{ <service>_version }}
container_name: <service>
restart: unless-stopped
user: "{{ docker_user_puid }}"
environment:
- PUID={{ docker_user_puid }}
- PGID={{ docker_user_pgid }}
- TZ={{ timezone }}
ports:
- '{{ <service>_port }}:<internal_port>' # REQUIRED if service has web interface
volumes:
- {{ <service>_folder }}:/config
# No explicit network needed - default Docker bridge network is sufficient
```
## Multi-Container Services
Use the `<service>-stack` folder pattern:
```yaml
# vars/main.yaml defines:
# <service>_parent_folder: "{{ docker_storage_folder }}/<service>-stack"
# <service>_folder: "{{ <service>_parent_folder }}/<service>"
# <service>_database_folder: "{{ <service>_parent_folder }}/database"
services:
<service>:
image: <image>:{{ <service>_version }}
container_name: <service>
restart: unless-stopped
user: "{{ docker_user_puid }}"
environment:
- PUID={{ docker_user_puid }}
- PGID={{ docker_user_pgid }}
- TZ={{ timezone }}
- DATABASE_URL=postgresql://db:5432/appdb # Use container names for internal communication
ports:
- '{{ <service>_port }}:<internal_port>'
volumes:
- {{ <service>_folder }}:/config # Points to <service>-stack/<service>/
networks:
- <service>_net
depends_on:
- db
db:
image: postgres:latest
container_name: <service>_db
restart: unless-stopped
environment:
- POSTGRES_DB=appdb
volumes:
- {{ <service>_database_folder }}:/var/lib/postgresql/data # Points to <service>-stack/database/
networks:
- <service>_net
# NO port mapping - internal access only
networks:
<service>_net:
driver: bridge
```
## Best Practices
### Single-Container Templates
- Default Docker bridge networking is usually sufficient
- Expose ports when the service provides an HTTP-based interface that users or the reverse proxy must reach
- Backend-only services with no user-facing HTTP interface can skip port exposure
### Multi-Container Templates
- Define an explicit Docker network for stack isolation
- Use internal container names for inter-service communication, for example `http://postgres:5432`
- Use `depends_on` to define container startup order
- Only expose ports for the container that users or the reverse proxy need to reach
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!