2025-11-06 23:09:44 +01:00
|
|
|
# Centralized Services Configuration
|
|
|
|
|
# Subdomains and Caddy settings for all services
|
|
|
|
|
|
|
|
|
|
# Edit these subdomains to match your preferences
|
|
|
|
|
subdomains:
|
|
|
|
|
# Monitoring Services (on watchtower)
|
2025-12-01 11:16:47 +01:00
|
|
|
ntfy: ntfy
|
2026-09-11 22:43:56 +02:00
|
|
|
# DEPRECATED 2026-09-11 — Uptime Kuma is decommissioned and this subdomain no
|
|
|
|
|
# longer resolves to anything. Kept only because the deprecated monitoring
|
|
|
|
|
# blocks still template it into uptime_kuma_api_url. See archive/uptime_kuma/.
|
2025-12-01 11:16:47 +01:00
|
|
|
uptime_kuma: uptime
|
2025-11-06 23:09:44 +01:00
|
|
|
|
|
|
|
|
# VPN Infrastructure (on spacey)
|
2025-12-01 11:16:47 +01:00
|
|
|
headscale: headscale
|
2025-11-06 23:09:44 +01:00
|
|
|
|
|
|
|
|
# Core Services (on vipy)
|
2025-12-01 11:16:47 +01:00
|
|
|
vaultwarden: vault
|
2025-12-01 12:14:25 +01:00
|
|
|
forgejo: forgejo
|
2025-12-06 23:44:17 +01:00
|
|
|
lnbits: wallet
|
2025-11-06 23:09:44 +01:00
|
|
|
|
|
|
|
|
# Secondary Services (on vipy)
|
2025-12-07 19:02:50 +01:00
|
|
|
ntfy_emergency_app: avisame
|
2025-12-06 23:44:17 +01:00
|
|
|
personal_blog: pablohere
|
2025-11-06 23:09:44 +01:00
|
|
|
|
|
|
|
|
# Memos (on memos-box)
|
2025-12-01 11:16:47 +01:00
|
|
|
memos: memos
|
2025-12-14 22:15:29 +01:00
|
|
|
|
|
|
|
|
# Mempool Block Explorer (on mempool_box, proxied via vipy)
|
|
|
|
|
mempool: mempool
|
2025-11-06 23:09:44 +01:00
|
|
|
|
2026-08-08 12:00:27 +02:00
|
|
|
# DATUM Gateway dashboard (on knots_box, proxied via vipy)
|
|
|
|
|
datum_gateway: datum
|
|
|
|
|
|
2025-11-06 23:09:44 +01:00
|
|
|
# Caddy configuration
|
|
|
|
|
caddy_sites_dir: /etc/caddy/sites-enabled
|
2025-11-14 23:36:00 +01:00
|
|
|
|
|
|
|
|
# Service-specific settings shared across playbooks
|
|
|
|
|
service_settings:
|
|
|
|
|
ntfy:
|
|
|
|
|
topic: alerts
|
|
|
|
|
headscale:
|
|
|
|
|
namespace: counter-net
|
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
|
|
|
mempool:
|
|
|
|
|
# The frontend port is needed in two places on two different hosts: the
|
|
|
|
|
# mempool role deploys it on mempool-box, and the Caddy play proxies to it
|
|
|
|
|
# from the edge host. A role default cannot serve the second play, so it
|
|
|
|
|
# lives here rather than in roles/mempool/defaults.
|
|
|
|
|
frontend_port: 8080
|
fulcrum: convert to a role, de-Uptime-Kuma the health check
685-line playbook becomes 33 lines plus a 426-line role
(install/service/healthcheck phases, six templates, one handler).
fulcrum_vars.yml is deleted; its content is the role's defaults.
Verified: fulcrum untouched - active since 2026-07-29 (no restart), 192G datadir,
height 966842, bitcoind and db_mem unchanged on disk. Second run changed=1 (the
arming run, changed_when: false aside). vipy changed=0.
THREE PRE-EXISTING LANDMINES the check-mode diff caught, any of which a faithful
extraction would have detonated:
- bitcoin_rpc_host was "192.168.1.140", commented "IP of knots_box_local". But
.140 is fulcrum-box ITSELF; knots-box is .135. The DHCP leases had reshuffled -
the fifth instance of this same disease in this estate. The live config had
been hand-corrected to knots-box; running the playbook would have reverted it
and pointed Fulcrum at itself. Now addressed by Tailscale name.
- The `Restart fulcrum` handler was guarded by uptime_kuma_enabled, so the three
tasks that notify it (SSL cert, fulcrum.conf, systemd unit) could not restart
anything. A config change applied to disk, reported success, and silently never
took effect. That is worse than the other banner casualties: it makes the
deployment itself lie. Ungated.
- db_mem was about to go 2048 -> 4448 (75% of 5931MB RAM), leaving ~1.4GB for the
OS and Fulcrum's non-cache memory. The live value had been hand-tuned down.
fulcrum_db_mem_mb_override pins it. Note set_fact outranks role defaults, so
the calculation itself has to honour the override.
MY OWN ERROR, third instance: retyping `copy:` as `template:` lost `owner:` on
the banner and on fulcrum.conf. Rather than keep catching these by eye, every
managed path's owner/group/mode is now compared against `git show HEAD:`
mechanically - 12/12 match.
The health check timer had not fired since 2026-02-17 while reporting `active`
and `enabled`. It is OnBootSec + OnUnitActiveSec with no OnCalendar: OnBootSec
elapses once, and OnUnitActiveSec needs the SERVICE to have run this boot to have
anything to schedule from. Restarting the timer does not supply that; running the
service does, so the role now runs the check once after enabling. Also dropped
`Requires=fulcrum.service` from the timer - on a timer that means "stop watching
when the watched thing stops".
Diagnostic note: NextElapseUSecRealtime is always empty for a monotonic timer, so
it reads as broken even when healthy. I misread it once and wrongly called the
timer dead. Use NextElapseUSecMonotonic or systemctl list-timers.
fulcrum_ssl_port and fulcrum_tailscale_hostname moved to services_config.yml -
the socket-proxy play on the edge host needs them and a role default cannot reach
a second play.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-13 18:02:00 +02:00
|
|
|
fulcrum:
|
|
|
|
|
# Same shape as mempool: the fulcrum role deploys on fulcrum-box, and the
|
|
|
|
|
# socket-proxy play publishes the SSL port from the edge host. A role default
|
|
|
|
|
# is invisible to that second play.
|
|
|
|
|
ssl_port: 50002
|
|
|
|
|
tailscale_hostname: fulcrum-box
|