Getting started
Sections
Prerequisites
The debops.docker_service role requires Docker Engine to be already
installed on the host. Use the debops.docker_server role to set up
Docker before using this role. The host must be included in both the
[debops_service_docker_server] and [debops_service_docker_service]
Ansible inventory groups.
The role uses the community.docker Ansible collection to manage containers.
The python3-docker package is installed automatically to provide the
required Python bindings.
The role imports the debops.secret role to provide access to the
secret variable. This allows service definitions to use the
lookup("password", ...) plugin to auto-generate and store secrets in
the DebOps secret directory on the Ansible Controller.
Default setup
If you don't specify any configuration, the role will not create any containers.
You need to define at least one service entry with name and image
parameters.
When a service has an nginx block with enabled: true, the role
automatically configures an nginx reverse proxy virtual host that
forwards traffic to the container. SSL/TLS is handled by the DebOps PKI
infrastructure.
For complete deployment examples of popular applications (Grafana, VictoriaMetrics, Vaultwarden, Bugsink, Homepage and more), see the Deployment guides page.
Nginx reverse proxy
The role integrates with debops.nginx to automatically set up reverse
proxy virtual hosts for container services. For each service with nginx
configuration, the role generates:
An nginx upstream pointing to
127.0.0.1:<port>A server block with the specified FQDN, proxying to the upstream
The container must expose the relevant port on 127.0.0.1 for this to work.
A typical port mapping looks like 127.0.0.1:8428:8428, which binds the
container port to localhost only -- nginx then handles external
access with SSL termination.
Example inventory
To deploy Docker container services on a host, it needs to be included in the appropriate Ansible inventory groups:
[debops_all_hosts]
hostname
[debops_service_docker_server]
hostname
[debops_service_docker_service]
hostname
Minimal service example
Deploy a VictoriaMetrics time series database with nginx reverse proxy:
# ansible/inventory/host_vars/hostname/docker_service.yml
docker_service__host_services:
- name: 'victoriametrics'
image: 'victoriametrics/victoria-metrics:v1.93.0'
ports:
- '127.0.0.1:8428:8428'
volumes:
- '/srv/docker/victoriametrics/data:/victoria-metrics-data'
command: '-retentionPeriod=12 -selfScrapeInterval=10s'
nginx:
enabled: true
fqdn: 'vmetrics.example.com'
port: '8428'
Multiple services example
Deploy VictoriaMetrics and Grafana side by side:
docker_service__host_services:
- name: 'victoriametrics'
image: 'victoriametrics/victoria-metrics:v1.93.0'
ports:
- '127.0.0.1:8428:8428'
volumes:
- '/srv/docker/victoriametrics/data:/victoria-metrics-data'
command: '-retentionPeriod=12 -selfScrapeInterval=10s'
memory: '512m'
nginx:
enabled: true
fqdn: 'vmetrics.example.com'
port: '8428'
- name: 'grafana'
image: 'grafana/grafana:11.0.0'
ports:
- '127.0.0.1:3000:3000'
volumes:
- '/srv/docker/grafana/data:/var/lib/grafana'
env:
GF_SERVER_ROOT_URL: 'https://grafana.example.com'
GF_SECURITY_ADMIN_PASSWORD: '{{ lookup("password", secret
+ "/docker_service/grafana/admin_password") }}'
nginx:
enabled: true
fqdn: 'grafana.example.com'
port: '3000'
Example playbook
If you are using this role without DebOps, here's an example Ansible playbook
that uses the debops.docker_service role:
---
- name: Manage Docker container services
collections: [ 'debops.debops', 'debops.roles01',
'debops.roles02', 'debops.roles03' ]
hosts: [ 'debops_service_docker_service' ]
become: True
environment: '{{ inventory__environment | d({})
| combine(inventory__group_environment | d({}))
| combine(inventory__host_environment | d({})) }}'
pre_tasks:
- name: Define variables used by Ansible roles
ansible.builtin.import_role:
name: 'secret'
tags: [ 'role::secret', 'role::docker_service' ]
- name: Build docker_service nginx configuration
ansible.builtin.import_role:
name: 'docker_service'
tasks_from: 'build_nginx_vars'
tags: [ 'role::docker_service', 'skip::docker_service',
'role::nginx', 'skip::nginx' ]
- name: Build docker_service postgresql configuration
ansible.builtin.import_role:
name: 'docker_service'
tasks_from: 'build_postgresql_vars'
tags: [ 'role::docker_service', 'skip::docker_service',
'role::postgresql', 'skip::postgresql' ]
roles:
- role: keyring
tags: [ 'role::keyring', 'skip::keyring' ]
keyring__dependent_gpg_keys:
- '{{ nginx__keyring__dependent_apt_keys }}'
when: docker_service__nginx__dependent_servers | d([]) | length > 0
- role: apt_preferences
tags: [ 'role::apt_preferences', 'skip::apt_preferences' ]
apt_preferences__dependent_list:
- '{{ nginx__apt_preferences__dependent_list }}'
when: docker_service__nginx__dependent_servers | d([]) | length > 0
- role: ferm
tags: [ 'role::ferm', 'skip::ferm' ]
ferm__dependent_rules:
- '{{ nginx__ferm__dependent_rules }}'
when: docker_service__nginx__dependent_servers | d([]) | length > 0
- role: python
tags: [ 'role::python', 'skip::python' ]
python__dependent_packages3:
- '{{ docker_service__python__dependent_packages3 }}'
- '{{ nginx__python__dependent_packages3
if (docker_service__nginx__dependent_servers | d([]) | length > 0)
else [] }}'
python__dependent_packages2:
- '{{ nginx__python__dependent_packages2
if (docker_service__nginx__dependent_servers | d([]) | length > 0)
else [] }}'
- role: postgresql
tags: [ 'role::postgresql', 'skip::postgresql' ]
postgresql__dependent_roles:
- '{{ docker_service__postgresql__dependent_roles }}'
postgresql__dependent_databases:
- '{{ docker_service__postgresql__dependent_databases }}'
postgresql__dependent_pgpass:
- '{{ docker_service__postgresql__dependent_pgpass }}'
when: docker_service__postgresql__dependent_roles | d([]) | length > 0
- role: nginx
tags: [ 'role::nginx', 'skip::nginx' ]
nginx__dependent_servers:
- '{{ docker_service__nginx__dependent_servers }}'
nginx__dependent_upstreams:
- '{{ docker_service__nginx__dependent_upstreams }}'
when: docker_service__nginx__dependent_servers | d([]) | length > 0
- role: docker_service
tags: [ 'role::docker_service', 'skip::docker_service' ]