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.
52 lines
2.0 KiB
YAML
52 lines
2.0 KiB
YAML
---
|
|
# Register this Site's logical network with Caddy.
|
|
#
|
|
# Copied from ansible-playbooks/caddy/roles/register/tasks/main.yaml: this repo
|
|
# carries its own deployment, so it cannot include that file by path. Keep the
|
|
# two in step.
|
|
#
|
|
# Caddy is the *base* unit and knows nothing about its upstreams. A service adds
|
|
# itself by writing two files into the Quadlet directory:
|
|
#
|
|
# 1. its own <name>.network unit, and
|
|
# 2. a drop-in next to caddy.container that pulls that network into Caddy.
|
|
#
|
|
# Caddy itself is owned by ansible-playbooks/caddy/playbook.yml; this play only
|
|
# registers with it. The including play defines a "Restart Caddy" handler.
|
|
|
|
- name: 'Create the {{ network_name }} network unit'
|
|
ansible.builtin.copy:
|
|
dest: '{{ quadlet_dir }}/{{ network_name }}.network'
|
|
owner: '{{ podman_user }}'
|
|
group: '{{ podman_user }}'
|
|
mode: '0644'
|
|
content: |
|
|
# {{ network_name }} — logical app network.
|
|
# Managed by Ansible. Do not edit by hand.
|
|
#
|
|
# NetworkName pins the Podman network name. Without it Quadlet would
|
|
# create "systemd-{{ network_name }}".
|
|
#
|
|
# isolate blocks traffic between separate Podman networks, so a container
|
|
# on this network cannot reach one that is only on another. Caddy and any
|
|
# shared service still reach it, because they are members of it.
|
|
[Network]
|
|
NetworkName={{ network_name }}_net
|
|
Options=isolate=true
|
|
notify: Restart Caddy
|
|
|
|
- name: 'Register {{ network_name }} with Caddy'
|
|
ansible.builtin.copy:
|
|
dest: '{{ quadlet_dir }}/{{ caddy_name }}.container.d/50-{{ network_name }}.conf'
|
|
owner: '{{ podman_user }}'
|
|
group: '{{ podman_user }}'
|
|
mode: '0644'
|
|
content: |
|
|
# Added by the {{ network_name }} playbook. Do not edit by hand.
|
|
#
|
|
# Quadlet merges this into caddy.container. Deleting this file removes
|
|
# the network from Caddy on the next daemon-reload.
|
|
[Container]
|
|
Network={{ network_name }}.network
|
|
notify: Restart Caddy
|