Files
tanshu 537a4f1e46 Match the deploy system to hops and greatbear
menu-admin was the odd one out: it built from the working directory with a date
tag and a multi-arch manifest, deployed with `-e tag=`, and kept the Docker-era
container name. The other two apps build from `git archive HEAD` and tag with the
commit, so what runs on the host is exactly what git knows about; build only for
the architecture emily actually runs; and use one slug for the container, its
network and its data directory.

The build is now their three lines: `podman build --platform linux/arm64` from
`git archive HEAD`, tagged `:<commit>` and `:latest`, pushed with `podman push`
rather than a manifest. `deploy.sh` pushes the commit first, then refuses a dirty
tracked tree or a HEAD that is not origin/main — which is what makes the commit
tag trustworthy — takes the same `--force` and `--no-push`, and ends in the same
`-u tanshu ... -e image_tag=<commit>`. Its own lint/typecheck/test gate stays,
but behind `--checks`, so a plain deploy behaves as theirs does.

The registry credential moves into vars/default.yml and the role logs in, pulls
and logs out around it, as their roles do. The image is only pulled at deploy
time, so the unit keeps podman's default `Pull=missing` and a reboot never needs
the registry. This is the same plaintext credential the other two repos carry.

One real bug goes with it: the healthcheck gate ran before the handler that
restarts a changed unit, so a run that only changed the unit checked the stale
container. `meta: flush_handlers` before the gate is the fix the sibling repos
already made.

The container, network and data directory are all menu-<site> now. The dotted
Docker-era name and the NetworkAlias it needed are gone, so `podman logs
menu-<site>` and `systemctl --user status menu-<site>` are the same two commands
across all three apps. The Dockerfile keeps its name for the same reason: podman
reads it as readily as a Containerfile, and the siblings use that name too.
2026-10-16 11:10:59 +05:30

47 lines
2.1 KiB
YAML

---
# Deploys the menu app for one or more Sites as rootless Podman Quadlet units on
# emily, behind the fleet's shared Caddy unit (caddy/playbook.yml in the
# ansible-playbooks repo). It lives here, beside the app it deploys.
#
# Connects as the container user and runs everything as that user: the Quadlet
# units belong to it, so the connection's PAM session is what makes
# `systemctl --user` and `podman exec` work without any environment juggling.
# There is deliberately no `become`: root-only prerequisites (Podman,
# `loginctl enable-linger`, the low-port sysctl Caddy needs) belong to
# caddy/playbook.yml, which must have run on this host first.
#
# gather_facts is required: podman_user, podman_data_dir and quadlet_dir are
# derived from the user_id / user_dir facts.
#
# The inventory is the one difference from the sibling apps, which deploy a
# single app: this play carries three Sites and a var_file per Site.
#
# ./deploy.sh (repo root)
# SITE=greatbear ./deploy.sh one Site
# cd ansible && ansible-playbook -u tanshu --inventory=hosts playbook.yml -e image_tag=<commit>
- name: Deploy the menu app as rootless Podman Quadlets
hosts: menus
gather_facts: true
vars_files:
- vars/default.yml
pre_tasks:
- name: Load the vars file this Site names in the inventory
ansible.builtin.include_vars:
file: '{{ var_file }}'
when: var_file is defined
# This must happen before the app unit is started, not after: the generated
# unit references {{ network_name }}.network, and Quadlet fails *unit
# generation* — so `systemctl --user start` reports "unit not found" — when a
# referenced .network file does not exist yet. The same include writes the
# Caddy-side drop-in that attaches Caddy to this network.
- name: Register this Site's network with Caddy
ansible.builtin.include_tasks: '{{ playbook_dir }}/roles/register/tasks/main.yaml'
roles:
# The app: the data directory tree, the Quadlet unit, start + verify.
- menu-app
# Appends this Site's block to the shared Caddyfile and reloads Caddy.
- caddy