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.
69 lines
3.0 KiB
YAML
69 lines
3.0 KiB
YAML
---
|
|
# Defaults shared by every Site. Each Site's own file is named by the `var_file`
|
|
# in ansible/hosts, and its slug is its inventory name.
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Rootless Podman / Quadlet
|
|
# ---------------------------------------------------------------------------
|
|
# Derived from the connection: this play carries no become, so the Quadlet
|
|
# units belong to whoever Ansible connects as. Requires gather_facts (set in
|
|
# playbook.yml). A host that has already run caddy/playbook.yml from the
|
|
# ansible-playbooks repo has the rootless prerequisites.
|
|
podman_user: "{{ ansible_facts['user_id'] }}"
|
|
podman_data_dir: "{{ ansible_facts['user_dir'] }}/podman-data"
|
|
quadlet_dir: "{{ ansible_facts['user_dir'] }}/.config/containers/systemd"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Image
|
|
# ---------------------------------------------------------------------------
|
|
registry: registry.tanshu.com
|
|
registry_username: ta-registry
|
|
registry_password: ff28a01f00c0f39315d94cd9dcb1e554968dba25676a8ea5f2be34e96a9a099f
|
|
|
|
image_name: '{{ registry }}/menu-admin'
|
|
tag: latest
|
|
# deploy.sh passes -e image_tag=<commit>; `tag` is the fallback when running the
|
|
# play by hand. Rollback = -e image_tag=<older-commit>.
|
|
image: '{{ image_name }}:{{ image_tag | default(tag) }}'
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# The Site
|
|
# ---------------------------------------------------------------------------
|
|
# One image serves every Site; this picks which config inside it to run. The
|
|
# inventory name is the slug, so the container, its network and its data
|
|
# directory are all menu-<site>.
|
|
site: '{{ inventory_hostname }}'
|
|
app_name: 'menu-{{ site }}'
|
|
container_name: '{{ app_name }}'
|
|
unit_name: '{{ container_name }}.service'
|
|
network_name: '{{ app_name }}'
|
|
|
|
# The image's own account (`node`), which keep-id maps onto podman_user.
|
|
app_uid: 1000
|
|
app_gid: 1000
|
|
|
|
# Port inside the container. Caddy proxies to it over menu-<site>_net; nothing
|
|
# is published on the host.
|
|
site_port: 3000
|
|
|
|
# podman builds an OCI image by default and drops the Dockerfile's HEALTHCHECK
|
|
# instruction, so the same check is declared on the Quadlet unit and the play
|
|
# gates on `podman healthcheck run`. node is in the image, and the sh -c podman
|
|
# wraps it in handles the quotes.
|
|
health_cmd: >-
|
|
node -e "fetch('http://127.0.0.1:{{ site_port }}/healthz').then(r =>
|
|
process.exit(r.ok ? 0 : 1)).catch(() => process.exit(1))"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Shared Caddy unit (caddy/playbook.yml in the ansible-playbooks repo)
|
|
# ---------------------------------------------------------------------------
|
|
caddy_name: caddy
|
|
caddyfile_path: '{{ podman_data_dir }}/{{ caddy_name }}/conf/Caddyfile'
|
|
|
|
# Appended to the shared Caddyfile by roles/caddy. The Site is served from the
|
|
# container name over menu-<site>_net; no host ports are involved.
|
|
snippet_block: |
|
|
{{ host }} {
|
|
reverse_proxy {{ container_name }}:{{ site_port }}
|
|
}
|