Run the Sites as rootless Podman Quadlets, and build with podman
The fleet on emily is rootless Podman with Quadlet units under ~/.config/containers/systemd and state in ~/podman-data, all behind one shared Caddy unit. This brings the menus in line instead of leaving them the last Docker deployment. The build moves with them: podman reads a Containerfile as readily as a Dockerfile, so the name now says which toolchain is real. The app is one .container and one .network file. Two details carry it. UserNS=keep-id maps the image's own node account onto the user that owns the units, so data/ and site.env stay owned by tanshu: plain tar backups, no subuids. 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. And the Site registers its own network with Caddy by writing a drop-in beside caddy.container, so Caddy never lists its upstreams and never changes when a Site is added. The unit keeps the Docker-era container name for the scripts and muscle memory that look it up, while the Caddyfile proxies to a dotless NetworkAlias, because a container name with dots in it is a liability in DNS. The unit keeps podman's Pull=missing, so a restart or a reboot never depends on the registry being reachable, while the play pulls explicitly at deploy time. That is also where a missing `podman login` for the private registry now fails, with the instruction, rather than as a unit that will not start. copy-site-data.sh moves a Site's data across, and is not a plain rsync: /var/lib/menu.* on monoco belongs to uid 1000 while the ssh user there is 1001, so the read needs sudo; monoco cannot ssh to emily, so the workstation relays the tar; and the extraction runs as tanshu on emily, which is what makes the files land owned by the user keep-id maps the app onto. It proves the copy by comparing a SHA-256 of the whole tree against the source and checking every file's owner. Not yet done: the copies themselves and the DNS move, which need a human.
This commit is contained in:
1 parent
c412181159
commit
e68f8ab00d
23 files changed
+876
-389
No files matched your search
+30
-10
@@ -1,15 +1,26 @@
|
||||
---
|
||||
# Deploys the menu app for one or more Sites. It lives here, beside the app it
|
||||
# deploys, and is run from this directory:
|
||||
# Deploys the menu app for one or more Sites as rootless Podman Quadlet units on
|
||||
# emily, behind the shared Caddy unit that ansible-playbooks/caddy owns. It lives
|
||||
# here, beside the app it deploys, and is run from this directory:
|
||||
#
|
||||
# make build-production TAG=<tag> (from the repo root)
|
||||
# ansible-playbook --inventory=hosts playbook.yml --limit hopsngrains
|
||||
# ./deploy.sh <tag> (repo root)
|
||||
# ansible-playbook --inventory=hosts playbook.yml --limit hopsngrains -e tag=<tag>
|
||||
#
|
||||
# One run deploys the Site: it starts the container and points the Site's web
|
||||
# address at it. Nothing older is kept serving, so there is no staged rollout —
|
||||
# deploying an earlier tag is the rollback.
|
||||
- hosts: menus
|
||||
become: true
|
||||
# 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` work without any environment juggling.
|
||||
#
|
||||
# gather_facts is required: podman_user and the home directory come from the
|
||||
# user_id / user_dir facts.
|
||||
#
|
||||
# The rootless-Podman prerequisites (installing podman, enabling lingering, the
|
||||
# low-port sysctl, creating the Quadlet directory) are deliberately NOT applied
|
||||
# here. They are the shared task file at
|
||||
# ansible-playbooks/caddy/roles/podman/tasks/main.yaml, and a host that has
|
||||
# already run ansible-playbooks/caddy/playbook.yml has them.
|
||||
- name: Deploy the menu app as rootless Podman Quadlets
|
||||
hosts: menus
|
||||
gather_facts: true
|
||||
vars_files:
|
||||
- vars/default.yml
|
||||
|
||||
@@ -19,7 +30,16 @@
|
||||
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:
|
||||
- network
|
||||
# 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
|
||||
Reference in new issue
Block a user