feat(docker_host): install Docker engine + compose plugin

Implements the docker_host role tasks: prerequisites, /etc/apt/keyrings
directory (ordered before the GPG key write), Docker APT key + repo, and
docker-ce/cli/containerd.io/compose-plugin install. Daemon hardening and
nftables.d integration remain deferred to Phase 2 (cluster + base firewall).
Updates defaults, README, and molecule verify to assert docker --version.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
sjat 2026-06-14 17:28:51 +02:00
parent d10f6de84b
commit 456c27d12b
4 changed files with 80 additions and 31 deletions

View file

@ -1,25 +1,25 @@
# docker_host
Docker engine + Compose runtime applied to every host in the `docker_hosts` group.
Provides the container platform that the per-service roles (one service = one role,
ADR-004) deploy their Compose stacks onto.
Installs the Docker CE engine and the Compose plugin on every host in the
`docker_hosts` group. Provides the container runtime that per-service roles
(one service = one role, ADR-004) deploy their Compose stacks onto.
> **Status: scaffolded, not yet implemented.** This role has no tasks yet — applying it
> is a no-op. It is wired into `playbooks/site.yml` so the full standard state is
> expressed end-to-end, and so `make lint` covers it. See `STATUS.md`.
## Scope
## Planned scope
This role covers the **engine install only**. The following are deferred to Phase 2
(when the Proxmox cluster and `base` host firewall exist):
- Install Docker engine + the Compose plugin, version-pinned (ADR-011).
- Daemon hardening: `iptables: false` (the host `base` firewall owns nftables, ADR-020),
log driver, `live-restore`, user-namespace remapping where practical (ADR-002).
- Render container forward/NAT rules into `/etc/nftables.d/*.nft` — the include hook the
`base` role's ruleset exposes (see `roles/base/README.md`).
- Provide the runtime the service roles deploy their Compose files onto.
- Daemon hardening (`iptables: false`, log driver, `live-restore`, userns remapping).
- Rendering container forward/NAT rules into `/etc/nftables.d/*.nft` (the `base` role
hook for container firewall integration, ADR-020).
## Variables
None yet. Placeholders will use the `docker_host__*` namespace (CLAUDE.md convention).
| Variable | Default | Description |
|---|---|---|
| `docker_host__packages` | `[docker-ce, docker-ce-cli, containerd.io, docker-compose-plugin]` | APT packages installed from the Docker CE repository |
All variables use the `docker_host__` double-underscore namespace (CLAUDE.md convention).
## Example
@ -31,4 +31,14 @@ None yet. Placeholders will use the `docker_host__*` namespace (CLAUDE.md conven
tags: [docker_host]
```
See ADR-004 (`docs/decisions/004-docker-model.md`) for the Docker & Compose model.
## Tags
All tasks carry the `packages` concern tag (APT package install, ADR-019).
## Related
- ADR-004 (`docs/decisions/004-docker-model.md`) — Docker & Compose model.
- ADR-020 (`docs/decisions/020-firewall.md`) — daemon hardening + `nftables.d`
integration (deferred to Phase 2).
- ADR-011 (`docs/decisions/011-update-management.md`) — version pinning policy
(future: pin Docker CE version explicitly).

View file

@ -1 +1,8 @@
---
# Docker engine install (ADR-004). Cluster-specific daemon hardening + nftables.d
# integration are deferred to when the cluster + host firewall exist.
docker_host__packages:
- docker-ce
- docker-ce-cli
- containerd.io
- docker-compose-plugin

View file

@ -4,8 +4,14 @@
gather_facts: true
tasks:
- name: Add verification tasks here
ansible.builtin.assert:
that: true
msg: "Replace this with real assertions"
- name: Verify docker binary is present
ansible.builtin.command: docker --version
register: docker_version_output
changed_when: false
tags: [verify]
- name: Assert docker --version succeeded
ansible.builtin.assert:
that: docker_version_output.rc == 0
msg: "docker --version failed — Docker was not installed correctly"
tags: [verify]

View file

@ -1,13 +1,39 @@
---
# docker_host — Docker engine + Compose runtime for hosts in the docker_hosts group.
#
# SCAFFOLDED, NOT YET IMPLEMENTED. This role is referenced by playbooks/site.yml so the
# full standard state is expressed end-to-end, but it has no tasks yet — applying it is a
# no-op. See STATUS.md ("Scaffolded but empty") and ADR-004 (Docker & Compose model).
#
# Planned scope (ADR-002/004/020):
# - install Docker engine + compose plugin (version-pinned, per ADR-011)
# - daemon hardening: iptables:false (host nftables owns the firewall, ADR-020),
# log-driver, live-restore, userns where practical
# - render container forward/NAT rules into /etc/nftables.d/*.nft (the base-role hook)
# - deploy per-service Compose stacks from the service roles (one service = one role)
- name: Install prerequisites
ansible.builtin.apt:
name: [ca-certificates, curl, gnupg]
state: present
update_cache: true
tags: [packages]
- name: Ensure /etc/apt/keyrings exists
ansible.builtin.file:
path: /etc/apt/keyrings
state: directory
mode: "0755"
tags: [packages]
- name: Add Docker's APT GPG key
ansible.builtin.get_url:
url: https://download.docker.com/linux/debian/gpg
dest: /etc/apt/keyrings/docker.asc
mode: "0644"
tags: [packages]
- name: Add the Docker APT repository
ansible.builtin.apt_repository:
repo: >-
deb [arch={{ 'amd64' if ansible_architecture == 'x86_64' else ansible_architecture }}
signed-by=/etc/apt/keyrings/docker.asc]
https://download.docker.com/linux/debian
{{ ansible_distribution_release }} stable
filename: docker
state: present
tags: [packages]
- name: Install Docker engine + compose plugin
ansible.builtin.apt:
name: "{{ docker_host__packages }}"
state: present
update_cache: true
tags: [packages]