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.
This commit is contained in:
1 parent
e68f8ab00d
commit
537a4f1e46
21 files changed
+407
-307
No files matched your search
@@ -1,49 +1,46 @@
|
||||
# {{ container_name }} — rootless Podman Quadlet unit.
|
||||
# Managed by Ansible (menu-admin/roles/menu-app). Do not edit by hand.
|
||||
#
|
||||
# Joins {{ network_name }}.network, written by roles/register — the same include
|
||||
# that attaches Caddy to it. Caddy reaches the app by container name, so nothing
|
||||
# is published on the host and the app is not reachable from outside the Podman
|
||||
# network at all.
|
||||
# This unit joins {{ network_name }}.network, which is created by
|
||||
# roles/register — the same include that attaches the shared Caddy unit to it,
|
||||
# so Caddy can resolve {{ container_name }} by name.
|
||||
|
||||
[Unit]
|
||||
Description=Menu app for {{ host }}
|
||||
Description=Menu app for {{ host }} ({{ site }})
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Container]
|
||||
ContainerName={{ container_name }}
|
||||
Image={{ image_name }}:{{ image_tag }}
|
||||
Image={{ image }}
|
||||
|
||||
# keep-id maps the image's own account — `node`, uid/gid {{ app_uid }} — onto
|
||||
# {{ podman_user }}, which is what keeps every file the app writes owned by
|
||||
# {{ podman_user }}, which keeps every file the app writes owned by
|
||||
# {{ podman_user }} on the host: plain tar/rsync backups, no subuids, no
|
||||
# `podman unshare`. The same mapping is why scripts/provision-site-env.sh writes
|
||||
# site.env with --userns=keep-id.
|
||||
# `podman unshare`. scripts/provision-site-env.sh writes site.env with the same
|
||||
# mapping rather than --user, which under rootless Podman would have produced a
|
||||
# subuid-owned file the app could not read.
|
||||
UserNS=keep-id:uid={{ app_uid }},gid={{ app_gid }}
|
||||
|
||||
# The alias is deliberately dotless. ContainerName keeps the Docker-era name so
|
||||
# operators and scripts find it, but a name with dots in it is a liability in
|
||||
# DNS, so {{ network_name }} is what the Caddyfile proxies to. Both resolve from
|
||||
# inside the network.
|
||||
NetworkAlias={{ network_name }}
|
||||
|
||||
Environment=MENU_ROOT=/data
|
||||
Environment=MENU_SITE_CONFIG=/app/config/{{ site }}.site.json
|
||||
Environment=SECURE_COOKIES=true
|
||||
Environment=LOG_LEVEL=info
|
||||
Environment=PORT={{ container_port }}
|
||||
Environment=PORT={{ site_port }}
|
||||
|
||||
# Everything the app writes: data/ (originals, drafts, published, site.json,
|
||||
# sections.json) and site.env. The Site's own config is baked into the image and
|
||||
# read from /app.
|
||||
Volume={{ app_root }}:/data
|
||||
Volume={{ host_directory }}:/data
|
||||
|
||||
Network={{ network_name }}.network
|
||||
|
||||
# podman builds an OCI image by default and drops the Containerfile's
|
||||
# HEALTHCHECK instruction, so the same check is declared here and the play gates
|
||||
# on it with `podman healthcheck run`. node is in the image.
|
||||
# No PublishPort on purpose: Caddy reaches the app over {{ network_name }}_net,
|
||||
# so nothing is exposed on the host.
|
||||
|
||||
# podman builds an OCI image by default and drops the Dockerfile's HEALTHCHECK
|
||||
# instruction, so the same check is declared here and the play gates on it with
|
||||
# `podman healthcheck run`. node is in the image.
|
||||
HealthCmd={{ health_cmd }}
|
||||
HealthInterval=30s
|
||||
HealthTimeout=5s
|
||||
|
||||
Reference in new issue
Block a user