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:

name

Required. Name of the Docker Compose project. Used as the project directory name under docker_compose_service__data_path (unless compose_dir is specified), the nginx configuration filename, and an identifier in role tasks. Must be unique across all service lists.

state

Optional. Defines the desired state of the Compose project. Supported values:

  • present (default): project is created and brought up

  • stopped: project exists but all containers are stopped

  • absent: project is removed (docker compose down)

  • ignore: entry is skipped entirely (DebOps convention)

compose_dir

Optional, 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_src

Optional, string. Path to a Jinja2 template file for the docker-compose.yml, relative to the Ansible templates/ search path. Mutually exclusive with compose_content. One of compose_src or compose_content must be provided when state is present.

Template files are typically placed in the DebOps resources directory:

ansible/docker_compose_service/by-host/<hostname>/
  <name>/docker-compose.yml
compose_content

Optional, string. Inline content for the docker-compose.yml file. Mutually exclusive with compose_src. Useful for simple projects that don't need a separate template file.

compose_files

Optional, list of dictionaries. Additional Compose files to deploy into the project directory (e.g. hardware acceleration overlays). Each entry has:

src

Required, string. Path to a Jinja2 template, relative to the Ansible templates/ search path.

dest

Optional, string. Destination path within the project directory. Defaults to the basename of src. Nested paths such as fragments/base.yml are supported; the role creates the parent directory before rendering the file.

env

Optional, dictionary. Environment variables written to the .env file in the project directory. Keys are variable names, values are strings. Sensitive values such as passwords can be auto-generated using the lookup("password", secret + "/docker_compose_service/<name>/...") pattern. Mutually exclusive with env_file_src.

env_file_src

Optional, string. Path to a Jinja2 template for the .env file, relative to the Ansible templates/ search path. Use this instead of env when you need full control over the .env file format. Mutually exclusive with env.

pull

Optional, boolean. Whether to run docker compose pull before bringing the project up. Defaults to docker_compose_service__pull (True).

remove_orphans

Optional, boolean. Whether to remove containers for services not defined in the Compose file. Defaults to True.

data_dirs

Optional, 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:

path

Required, string. Absolute path of the directory to create.

owner

Optional, string. Directory owner (name or UID). When omitted, the ansible.builtin.file module leaves the parameter unset. A newly created directory is owned by the effective user of the task (typically root when the playbook uses privilege escalation). An already existing directory keeps its current owner. Ownership is not inherited from the parent directory.

group

Optional, 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.

mode

Optional, string. Directory permissions. Defaults to 0755.

config_files

Optional, 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:

dest

Required, string. Absolute path on the host where the file will be created. Parent directories are created automatically.

content

Optional, string. Inline file content. Mutually exclusive with src. Jinja2 expressions are evaluated at variable expansion time.

src

Optional, string. Path to a Jinja2 template file, relative to the Ansible templates/ search path. Mutually exclusive with content.

mode

Optional, string. File permissions. Defaults to 0644.

owner

Optional, string. File owner. Defaults to root.

group

Optional, string. File group. Defaults to root.

config_dir

Optional, 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.filetree and all files are rendered as Jinja2 templates. The Compose project is automatically recreated when any file changes.

src

Required, 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 under dest.

dest

Required, string. Absolute path on the host where the rendered files will be placed.

mode

Optional, string. Default file permissions for rendered files. Defaults to 0644.

owner

Optional, string. File owner. Defaults to root.

group

Optional, string. File group. Defaults to root.

nginx

Optional, 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_ports

Optional, list of dictionaries. Firewall rules to apply for ports published directly to the network (not via 127.0.0.1 behind 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 ACCEPT rule in the DOCKER-USER chain for each source CIDR.

  • A trailing default-deny rule (REJECT or DROP) 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:

port

Required, integer or string. The host-side published port. Used in the generated rule name. On the default DOCKER-USER chain this is also the dport match unless container_port is set.

container_port

Optional, integer or string. Destination port to match in DOCKER-USER after Docker DNAT (the container-side port). Defaults to port. Set this when the Compose mapping is not 1:1, for example port: 8080 and container_port: 80 for 8080:80. Ignored when chain is INPUT (host-network containers still match port).

protocol

Optional, string. IP protocol: tcp or udp. Defaults to docker_compose_service__ferm__default_protocol (tcp).

allow

Optional, 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 ACCEPT rule per entry is generated, followed by a single default-deny rule.

action_default

Optional, string. Action for traffic not matching any allow source. Supported values: reject (default, sends ICMP/TCP-reset reply) and drop (silently discards). Defaults to docker_compose_service__ferm__default_action.

chain

Optional, string. iptables chain where the rules are placed. Defaults to docker_compose_service__ferm__default_chain (DOCKER-USER). Override to INPUT only for containers using network_mode: host, where traffic genuinely traverses INPUT instead of FORWARD.

comment

Optional, 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-USER

The iptables chain used when a published_ports entry does not specify chain. See the note in docker_compose_service__services published_ports parameters for why DOCKER-USER is the correct default.

docker_compose_service__ferm__default_protocol

Default value: tcp

IP protocol assumed when a published_ports entry omits protocol.

docker_compose_service__ferm__default_action

Default value: reject

Default-deny action applied to sources not in allow. reject sends a TCP reset or ICMP admin-prohibited reply; drop silently discards the packet. reject is 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

enabled

Required, boolean. If True, an nginx reverse proxy is configured for this service. If False or the nginx dictionary is absent, no proxy is created.

fqdn

Optional, string. Fully Qualified Domain Name for the nginx server block. Defaults to <name>.<docker_compose_service__domain>.

port

Required (when enabled: true), string. The host-side port that nginx should proxy to. This must match the port exposed by the Compose service on 127.0.0.1.

type

Optional, string. The nginx server template type. Defaults to proxy. See debops.nginx documentation for other available types.

proxy_headers

Optional, boolean. If True (default), standard proxy headers are included (X-Real-IP, X-Forwarded-For, X-Forwarded-Proto, Host).

proxy_options

Optional, YAML text block. Additional nginx directives placed inside the location block, after the proxy headers.

options

Optional, YAML text block. Additional nginx directives placed inside the server block.

allow

Optional, list of strings. IP addresses or CIDR networks allowed to access the service. When empty (default), no access restrictions are applied.

deny_all

Optional, boolean. If True and allow is specified, a deny all directive is added after the allow rules. Defaults to False.

ssl

Optional, boolean. Enable HTTPS through DebOps PKI. When omitted, the debops.nginx role default applies (typically True).

auth_basic

Optional, boolean. Enable HTTP Basic Authentication. Defaults to False.

auth_basic_realm

Optional, string. The authentication realm displayed to users when auth_basic is enabled.