weeknotes_home_deploy¶
Deploys the weeknotes.home Django service from the daybook repository.
The role provisions a PostgreSQL database/user, syncs or checks out the daybook
source tree, installs the weeknotes-home uv dependency group, runs Django
migrations and static collection, installs a systemd gunicorn service, renders a
Traefik route, and verifies /healthz.
Requirements¶
Ubuntu/Debian target with systemd.
PostgreSQL provisioned through the included
postgres_installrole tasks.Traefik when
weeknotes_home_traefik_enabledis true.Real secrets supplied by the private control repo; this role’s public defaults intentionally use
CHANGEMEplaceholders and fail validation.
Example¶
- role: local.ops_library.weeknotes_home_deploy
vars:
weeknotes_home_deploy_method: rsync
weeknotes_home_source_path: /Users/jochen/projects/daybook
weeknotes_home_django_secret_key: "{{ service_secrets.django_secret_key }}"
weeknotes_home_postgres_password: "{{ service_secrets.postgres_password }}"
weeknotes_home_api_token: "{{ service_secrets.api_token }}"
weeknotes_home_traefik_host: weeknotes.home.wersdoerfer.de
weeknotes_home_basic_auth_user: "{{ traefik_secrets.basic_auth_user }}"
weeknotes_home_basic_auth_password: "{{ traefik_secrets.basic_auth_password }}"
weeknotes_home_cast_base_url: https://wersdoerfer.de
Key Variables¶
weeknotes_home_deploy_method:rsyncfor local/controller deploys orgitfor a clean checkout.weeknotes_home_source_path: controller checkout used inrsyncmode.weeknotes_home_git_repo,weeknotes_home_git_version: source used ingitmode.weeknotes_home_django_secret_key: required secret.weeknotes_home_postgres_password: required database user password.weeknotes_home_api_token: required owner-managed URL-safe bearer token (32-256 characters) protecting the open-comment and fold APIs. The same secret must be supplied to the Studio Daybook reconciler; it is never a browser-session credential.weeknotes_home_cast_base_url: optional public django-cast origin used to render edit and preview links for delivered drafts.weeknotes_home_traefik_host: hostname routed to the service.weeknotes_home_basic_auth_enabled: defaults totrue; enables the required trusted/external dual-router boundary.weeknotes_home_basic_auth_user,weeknotes_home_basic_auth_password: shared Traefik front-door credentials supplied by the private control repo. The role generates a bcrypt hash withhtpasswdunderno_log.weeknotes_home_basic_auth_password_hash: optional precomputed bcrypt hash; when set,htpasswdand the plaintext password are not required.weeknotes_home_internal_ip_ranges: RFC1918 and Tailnet source ranges that use the higher-priority router without Basic Auth.weeknotes_home_app_port: local gunicorn port, default10062.
Traefik Security Boundary¶
With the safe default (weeknotes_home_basic_auth_enabled: true), the generated
HTTPS configuration has two routers:
priority
120:Host(...) && ClientIP(...)for trusted LAN/Tailnet clients, preserving unattended Studio access to the bearer-protected machine APIs;priority
100:Host(...)for every other source, with Basic Auth before the existing headers, gzip, TLS, and backend service behavior.
The Basic Authorization header is removed before proxying. The open-comment
and fold APIs retain their independent bearer checks; unattended API clients
must use the trusted router, which forwards their Bearer header unchanged. The
external router reserves that header for Basic Auth and is intended for browser
UI access. The HTTP router only performs a permanent HTTPS redirect via
Traefik’s noop@internal service and never forwards request data to Django.
Disabling Basic Auth removes the source split and is only appropriate when an equivalent external boundary exists and the exception is documented by the private deployment. Trusted ranges must contain only private or explicitly trusted networks; never add public ISP prefixes.
When the shared credential changes, the private control repo must either redeploy this role or include its Traefik task in the shared credential rotation workflow so the derived bcrypt hash is refreshed.
Backup and Monitoring¶
This deploy role intentionally does not create backup or monitoring jobs. Wire
the deployed PostgreSQL database into Echoport and add a Nyxmon /healthz check
from the private ops-control repo, where service inventory, secrets, and backup
topology live.