Default variable details
Some of debops.docker_compose_service default variables have more extensive
configuration than simple strings or lists, here you can find documentation and
examples for them.
docker_compose_service__services
The docker_compose_service__*_services variables define Docker Compose
projects managed by this role. The variables are lists of YAML dictionaries,
each dictionary defines a Compose project. Entries from multiple lists are
merged together in order: default, all hosts, group, host.
Examples
Minimal service definition (name and compose_src are required):
docker_compose_service__host_services:
- name: 'myapp'
compose_src: 'myapp/docker-compose.yml'
Service with environment variables and nginx reverse proxy:
docker_compose_service__host_services:
- name: 'immich'
compose_src: 'immich/docker-compose.yml'
env:
UPLOAD_LOCATION: '/mnt/photo'
DB_PASSWORD: '{{ lookup("password", secret
+ "/docker_compose_service/immich/db_password
chars=ascii_letters,digits length=32") }}'
IMMICH_VERSION: 'release'
nginx:
enabled: true
fqdn: 'immich.example.com'
port: '2283'
proxy_options: |
proxy_buffering off;
client_max_body_size 50G;
proxy_read_timeout 600s;
proxy_send_timeout 600s;
send_timeout 600s;
Service with inline Compose content (no template file needed):
docker_compose_service__host_services:
- name: 'whoami'
compose_content: |
services:
whoami:
image: traefik/whoami:latest
ports:
- '127.0.0.1:8080:80'
restart: unless-stopped
nginx:
enabled: true
fqdn: 'whoami.example.com'
port: '8080'
Service with additional Compose files (e.g. hardware acceleration overlay):
docker_compose_service__host_services:
- name: 'immich'
compose_src: 'immich/docker-compose.yml'
compose_files:
- src: 'immich/hwaccel.ml.yml'
dest: 'hwaccel.ml.yml'
env:
IMMICH_VERSION: 'release'
Removing a previously deployed project:
docker_compose_service__host_services:
- name: 'old-project'
state: 'absent'
Syntax
Each entry in the services list is a YAML dictionary with the following parameters:
nameRequired. Name of the Docker Compose project. Used as the project directory name under
docker_compose_service__data_path(unlesscompose_diris specified), the nginx configuration filename, and an identifier in role tasks. Must be unique across all service lists.stateOptional. Defines the desired state of the Compose project. Supported values:
present(default): project is created and brought upstopped: project exists but all containers are stoppedabsent: project is removed (docker compose down)ignore: entry is skipped entirely (DebOps convention)
compose_dirOptional, string. Absolute path to the Docker Compose project directory on the host. Defaults to
{{ docker_compose_service__data_path }}/<name>. The directory is created automatically.compose_srcOptional, string. Path to a Jinja2 template file for the
docker-compose.yml, relative to the Ansibletemplates/search path. Mutually exclusive withcompose_content. One ofcompose_srcorcompose_contentmust be provided whenstateispresent.Template files are typically placed in the DebOps resources directory:
ansible/docker_compose_service/by-host/<hostname>/ <name>/docker-compose.yml
compose_contentOptional, string. Inline content for the
docker-compose.ymlfile. Mutually exclusive withcompose_src. Useful for simple projects that don't need a separate template file.compose_filesOptional, list of dictionaries. Additional Compose files to deploy into the project directory (e.g. hardware acceleration overlays). Each entry has:
srcRequired, string. Path to a Jinja2 template, relative to the Ansible
templates/search path.destOptional, string. Destination path within the project directory. Defaults to the basename of
src. Nested paths such asfragments/base.ymlare supported; the role creates the parent directory before rendering the file.
envOptional, dictionary. Environment variables written to the
.envfile in the project directory. Keys are variable names, values are strings. Sensitive values such as passwords can be auto-generated using thelookup("password", secret + "/docker_compose_service/<name>/...")pattern. Mutually exclusive withenv_file_src.env_file_srcOptional, string. Path to a Jinja2 template for the
.envfile, relative to the Ansibletemplates/search path. Use this instead ofenvwhen you need full control over the.envfile format. Mutually exclusive withenv.pullOptional, boolean. Whether to run
docker compose pullbefore bringing the project up. Defaults todocker_compose_service__pull(True).remove_orphansOptional, boolean. Whether to remove containers for services not defined in the Compose file. Defaults to
True.data_dirsOptional, list of dictionaries. Directories to create on the host before the Compose project is started. Useful for pre-creating mount point subdirectories (e.g. on NFS volumes) with specific ownership and permissions that the containerized application expects. Each entry has:
pathRequired, string. Absolute path of the directory to create.
ownerOptional, string. Directory owner (name or UID). When omitted, the
ansible.builtin.filemodule leaves the parameter unset. A newly created directory is owned by the effective user of the task (typicallyrootwhen the playbook uses privilege escalation). An already existing directory keeps its current owner. Ownership is not inherited from the parent directory.groupOptional, string. Directory group (name or GID). Same default behaviour as
owner: a new directory uses the effective group, an existing directory keeps its current group.modeOptional, string. Directory permissions. Defaults to
0755.
config_filesOptional, list of dictionaries. Configuration files to create on the host before bringing up the Compose project. Each entry creates a file that can be bind-mounted into containers via volumes defined in the Compose file. The Compose project is automatically recreated when a config file changes. Two modes are supported:
destRequired, string. Absolute path on the host where the file will be created. Parent directories are created automatically.
contentOptional, string. Inline file content. Mutually exclusive with
src. Jinja2 expressions are evaluated at variable expansion time.srcOptional, string. Path to a Jinja2 template file, relative to the Ansible
templates/search path. Mutually exclusive withcontent.modeOptional, string. File permissions. Defaults to
0644.ownerOptional, string. File owner. Defaults to
root.groupOptional, string. File group. Defaults to
root.
config_dirOptional, dictionary. A directory of template files to render on the host, useful for applications that need many configuration files. The directory tree is scanned using
community.general.filetreeand all files are rendered as Jinja2 templates. The Compose project is automatically recreated when any file changes.srcRequired, string. Path to a directory of template files on the Ansible Controller. Relative paths are resolved against the
templates/search path. The directory structure is replicated underdest.destRequired, string. Absolute path on the host where the rendered files will be placed.
modeOptional, string. Default file permissions for rendered files. Defaults to
0644.ownerOptional, string. File owner. Defaults to
root.groupOptional, string. File group. Defaults to
root.
nginxOptional, dictionary. When present and
enabled: true, configures an nginx reverse proxy virtual host for this service. See docker_compose_service__services nginx parameters for details.published_portsOptional, list of dictionaries. Firewall rules to apply for ports published directly to the network (not via
127.0.0.1behind nginx). See docker_compose_service__services published_ports parameters for details.
docker_compose_service__services published_ports parameters
The published_ports list within a service entry declares the ports that
the Compose project publishes directly to the network (i.e. bound to
0.0.0.0 or a specific LAN address rather than 127.0.0.1). For each
entry with a non-empty allow list the role generates:
An
ACCEPTrule in theDOCKER-USERchain for each source CIDR.A trailing default-deny rule (
REJECTorDROP) for all remaining sources on that port.
Entries with an empty or absent allow list are silently skipped (opt-in
behaviour: no published_ports key → no change to existing behaviour).
Important
Docker-published ports are processed in the FORWARD path, not
INPUT. A rule placed in INPUT silently fails to filter a published
container port. This integration uses the DOCKER-USER chain, which is
the correct location for per-port filtering of container traffic.
After Docker's DNAT the destination port seen in DOCKER-USER is the
container port, not the host-side published port. When the Compose
mapping is not 1:1 (for example 8080:80), set container_port to
the container-side value. The ferm role has no
ctorigdstport match, so the generated dport uses
container_port (defaulting to port) on DOCKER-USER.
Because of that, two mappings that share a container port and the
same protocol (for example TCP 8080:80 and TCP 8081:80) cannot
have independent allow lists: both rules match the same dport.
Give them the same allow list, or publish distinct container ports.
TCP and UDP on the same container port can still use separate
allow lists.
Examples
Restrict a port to a single VLAN:
docker_compose_service__host_services:
- name: 'ollama'
compose_src: 'ollama/docker-compose.yml'
published_ports:
- port: 11434
protocol: 'tcp'
allow: [ '192.0.2.0/24' ]
comment: 'Ollama API - monitoring VLAN only'
Multiple ports, mixed protocols:
docker_compose_service__host_services:
- name: 'myapp'
compose_src: 'myapp/docker-compose.yml'
published_ports:
- port: 8080
allow: [ '10.0.0.0/8' ]
comment: 'myapp HTTP'
- port: 9090
allow: [ '192.0.2.0/24' ]
action_default: 'drop'
comment: 'myapp metrics - monitoring VLAN only'
A container with network_mode: host (traffic lands in INPUT):
published_ports:
- port: 9100
chain: 'INPUT'
allow: [ '192.0.2.0/24' ]
comment: 'node-exporter - monitoring VLAN only'
Syntax
Each entry in the published_ports list is a YAML dictionary with the
following parameters:
portRequired, integer or string. The host-side published port. Used in the generated rule name. On the default
DOCKER-USERchain this is also thedportmatch unlesscontainer_portis set.container_portOptional, integer or string. Destination port to match in
DOCKER-USERafter Docker DNAT (the container-side port). Defaults toport. Set this when the Compose mapping is not 1:1, for exampleport: 8080andcontainer_port: 80for8080:80. Ignored whenchainisINPUT(host-network containers still matchport).protocolOptional, string. IP protocol:
tcporudp. Defaults todocker_compose_service__ferm__default_protocol(tcp).allowOptional, list of strings. Source IP addresses or CIDR networks that are permitted to reach the port. When absent or empty, no rules are emitted. When non-empty, one
ACCEPTrule per entry is generated, followed by a single default-deny rule.action_defaultOptional, string. Action for traffic not matching any
allowsource. Supported values:reject(default, sends ICMP/TCP-reset reply) anddrop(silently discards). Defaults todocker_compose_service__ferm__default_action.chainOptional, string. iptables chain where the rules are placed. Defaults to
docker_compose_service__ferm__default_chain(DOCKER-USER). Override toINPUTonly for containers usingnetwork_mode: host, where traffic genuinely traversesINPUTinstead ofFORWARD.commentOptional, string. Human-readable comment embedded in the generated ferm rule file. Defaults to
<service-name> port <port>/<protocol> (DOCKER-USER).
docker_compose_service ferm defaults
The following variables control the default behaviour of the published_ports
firewall integration. They apply to any port entry that does not override the
corresponding parameter explicitly.
docker_compose_service__ferm__default_chain
Default value:
DOCKER-USERThe iptables chain used when a
published_portsentry does not specifychain. See the note in docker_compose_service__services published_ports parameters for whyDOCKER-USERis the correct default.
docker_compose_service__ferm__default_protocol
Default value:
tcpIP protocol assumed when a
published_portsentry omitsprotocol.
docker_compose_service__ferm__default_action
Default value:
rejectDefault-deny action applied to sources not in
allow.rejectsends a TCP reset or ICMPadmin-prohibitedreply;dropsilently discards the packet.rejectis preferred as it gives the client an explicit signal rather than a timeout.
docker_compose_service__services nginx parameters
The nginx dictionary within a service entry controls the nginx
reverse proxy configuration. The role generates nginx upstream and
server block definitions that are passed to the debops.nginx role.
The parameters are identical to those in the debops.docker_service role.
Examples
Minimal nginx configuration:
nginx:
enabled: true
fqdn: 'app.example.com'
port: '8080'
Full nginx configuration with all options:
nginx:
enabled: true
fqdn: 'app.example.com'
port: '8080'
type: 'proxy'
proxy_headers: true
proxy_options: |
proxy_buffering off;
proxy_read_timeout 300s;
options: |
client_max_body_size 50m;
allow:
- '192.168.1.0/24'
- '10.0.0.0/8'
deny_all: true
auth_basic: true
auth_basic_realm: 'Restricted'
Syntax
enabledRequired, boolean. If
True, an nginx reverse proxy is configured for this service. IfFalseor thenginxdictionary is absent, no proxy is created.fqdnOptional, string. Fully Qualified Domain Name for the nginx server block. Defaults to
<name>.<docker_compose_service__domain>.portRequired (when
enabled: true), string. The host-side port that nginx should proxy to. This must match the port exposed by the Compose service on127.0.0.1.typeOptional, string. The nginx server template type. Defaults to
proxy. See debops.nginx documentation for other available types.proxy_headersOptional, boolean. If
True(default), standard proxy headers are included (X-Real-IP,X-Forwarded-For,X-Forwarded-Proto,Host).proxy_optionsOptional, YAML text block. Additional nginx directives placed inside the
locationblock, after the proxy headers.optionsOptional, YAML text block. Additional nginx directives placed inside the
serverblock.allowOptional, list of strings. IP addresses or CIDR networks allowed to access the service. When empty (default), no access restrictions are applied.
deny_allOptional, boolean. If
Trueandallowis specified, adeny alldirective is added after the allow rules. Defaults toFalse.sslOptional, boolean. Enable HTTPS through DebOps PKI. When omitted, the debops.nginx role default applies (typically
True).auth_basicOptional, boolean. Enable HTTP Basic Authentication. Defaults to
False.auth_basic_realmOptional, string. The authentication realm displayed to users when
auth_basicis enabled.