personal_infra/ansible/roles/mempool/tasks/deploy.yml
counterweight 356139290f
mempool: convert to a role, de-Uptime-Kuma the health checks
745-line playbook becomes 37 lines (the role, plus the Caddy play for the edge
host) and a 408-line role with docker/deploy/healthcheck phases and six
templates. mempool_vars.yml is deleted; its content is the role's defaults.

Three health checks are kept, not collapsed: Mempool is three moving parts and
knowing which one is down is the point. Each has its own script, unit, timer and
push_url, driven by a mempool_healthchecks list. The Uptime Kuma specifics are
gone - the embedded Python creating monitors over the API, the /tmp credentials
file, the push-URL file read back and parsed, three Environment= rewrites - and
the three live push URLs are preserved from the vault, so reporting is unchanged.

`Enable and start health check timers` and `Display deployment status` were both
guarded by uptime_kuma_enabled despite being deployment tasks. Third service in
a row with that pattern: the deprecation banner was applied to contiguous blocks,
so anything sitting near the push plumbing was disabled with it. Ungated.

TWO OWNERSHIP PROBLEMS, different in kind:

- MINE: I wrote `owner: root` on docker-compose.yml where the original says
  `owner: "{{ ansible_user }}"`. A straight violation of extract-mechanically-
  change-nothing, caught only by reading the check-mode diff line by line.
  Reverted to match the original.

- PRE-EXISTING, and dangerous: the playbook declared
  `owner: "{{ ansible_user }}"` (1000) on the MariaDB data directory, which the
  container owns as uid 999. Confirmed against `git show HEAD:` before
  concluding it was not mine. It had drifted since the containers were created
  and went unnoticed because the playbook had not been run since.

  This was not academic. The first real run pulled a newer mariadb:10.11 and
  recreated mempool-db; with the chown still in place MariaDB would have come
  back to a data directory it could not write. The role now ensures the
  directory exists and leaves ownership to the container. Verified after the
  run: /opt/mempool/mysql is still 999:999 and all three containers are healthy.

  This is a deliberate behaviour change, not part of the extraction. It is in
  this commit rather than a follow-up because the faithful version was never
  safe to run, so there was no intermediate state worth recording as verified.

mempool_frontend_port moved to services_config.yml: two hosts need it (this role
deploys the frontend, the Caddy play proxies to it from the edge host) and a role
default is invisible to the second play. caddy_site's parameter assert caught
this loudly - "'mempool_frontend_port' is undefined" - rather than silently.

Verified: check-mode diff clean apart from unavoidable check-mode artifacts;
first run ok=24 changed=5, zero failures; second run changed=2 - the two bare
`command:` tasks (pull, compose up) that have no changed_when and always report
changed. That is the idempotent floor. All three health checks report
ExecMainStatus 0 with their push URLs intact.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-12 18:49:11 +02:00

75 lines
2.3 KiB
YAML

---
- name: Create mempool directories
file:
path: "{{ item }}"
state: directory
owner: "{{ ansible_user }}"
group: "{{ ansible_user }}"
mode: '0755'
loop:
- "{{ mempool_dir }}"
- "{{ mempool_data_dir }}"
# MariaDB owns its own data directory. The container runs as uid 999 and has to
# create files in there; this playbook declared owner: {{ ansible_user }} (1000),
# which had been drifting from reality ever since the containers were created and
# would have broken MariaDB the first time it needed a new file. It went
# unnoticed only because the playbook had not been run since.
#
# So: ensure the directory exists, and let the container own it. On a fresh
# install the mariadb image's entrypoint sets ownership itself.
- name: Ensure the MariaDB data directory exists
file:
path: "{{ mempool_mysql_dir }}"
state: directory
- name: Create docker-compose.yml for Mempool
ansible.builtin.template:
src: docker-compose.yml.j2
dest: "{{ mempool_dir }}/docker-compose.yml"
owner: "{{ ansible_user }}"
group: "{{ ansible_user }}"
mode: '0644'
- name: Pull Mempool images
command: docker compose pull
args:
chdir: "{{ mempool_dir }}"
- name: Deploy Mempool containers with docker compose
command: docker compose up -d
args:
chdir: "{{ mempool_dir }}"
- name: Wait for MariaDB to be healthy
command: docker inspect --format='{{ '{{' }}.State.Health.Status{{ '}}' }}' mempool-db
register: mariadb_health
until: mariadb_health.stdout == 'healthy'
retries: 30
delay: 10
changed_when: false
- name: Wait for Mempool backend to start
uri:
url: "http://localhost:{{ mempool_backend_port }}/api/v1/backend-info"
method: GET
status_code: 200
timeout: 10
register: backend_check
until: backend_check.status == 200
retries: 30
delay: 10
ignore_errors: yes
- name: Wait for Mempool frontend to be available
uri:
url: "http://localhost:{{ mempool_frontend_port }}"
method: GET
status_code: 200
timeout: 10
register: frontend_check
until: frontend_check.status == 200
retries: 20
delay: 5
ignore_errors: yes
# ═════════════════════════════════════════════════════════════════════════