Cut the comment bloat from the Podman playbooks
Comment blocks now stay within three lines and explain only the non-obvious. Long histories, include examples, and commented-out code are gone. No task, key, or value changed; the only data change is comment text inside the generated unit files.
This commit is contained in:
1 parent
2aab1aec1e
commit
476a6d7cd0
85 files changed
+372
-2433
No files matched your search
@@ -1,27 +1,14 @@
|
||||
---
|
||||
# Caddy is its own playbook (caddy/playbook.yml) and a rootless Quadlet unit
|
||||
# there. These handlers run as the connection user, which is what makes
|
||||
# `systemctl --user` and `podman exec` work here.
|
||||
|
||||
# Notified by this role when the Caddyfile changes. A reload keeps existing
|
||||
# connections; a restart would briefly drop every hosted site.
|
||||
#
|
||||
# Note the config path: /etc/caddy/Caddyfile is the mount inside the container,
|
||||
# not {{ caddyfile_path }}, which is the host side of it.
|
||||
# A reload keeps existing connections. A restart would briefly drop every hosted site.
|
||||
# The config path is inside the container, not caddyfile_path on the host.
|
||||
- name: Reload Caddy configuration
|
||||
ansible.builtin.command: >-
|
||||
podman exec {{ caddy_name }} caddy reload --config /etc/caddy/Caddyfile
|
||||
changed_when: true
|
||||
listen: "Reload Caddy"
|
||||
|
||||
# Notified by caddy/roles/register when this service's network unit, or the
|
||||
# drop-in that attaches Caddy to it, is written. Quadlet has no live equivalent
|
||||
# of `docker network connect`, so the container has to be recreated — a brief
|
||||
# restart of every hosted site, not just this one. See caddy/readme.md,
|
||||
# "Trade-off worth knowing".
|
||||
#
|
||||
# Defined after the reload above so that when both are notified the cheap
|
||||
# config reload happens first.
|
||||
# Quadlet has no live equivalent of network connect, so Caddy is recreated and every hosted site restarts.
|
||||
# Defined after the reload so the cheap reload runs first.
|
||||
- name: Restart Caddy
|
||||
ansible.builtin.systemd_service:
|
||||
name: "{{ caddy_name }}.service"
|
||||
|
||||
@@ -1,17 +1,4 @@
|
||||
---
|
||||
# Append this site's block to the shared Caddyfile.
|
||||
#
|
||||
# The Caddyfile is a bind mount into the Caddy container, so Caddy sees the
|
||||
# change as soon as the file is written; the handler only asks Caddy to re-read
|
||||
# it. That is a reload, not a restart, so the other hosted sites are untouched.
|
||||
#
|
||||
# blockinfile is idempotent on its own via the marker, so there is no need to
|
||||
# slurp the file and compare first — which also matters because slurp *fails*
|
||||
# when the Caddyfile does not exist yet, on a host where the Caddy playbook has
|
||||
# not run.
|
||||
#
|
||||
# The marker is stable, so re-runs replace this site's block in place rather than
|
||||
# appending a second copy of it.
|
||||
- name: "Add the {{ host }} site block to the Caddyfile"
|
||||
ansible.builtin.blockinfile:
|
||||
path: "{{ caddyfile_path }}"
|
||||
|
||||
@@ -1,17 +1,11 @@
|
||||
---
|
||||
# Handlers run as the connection user, which is what makes `systemctl --user`
|
||||
# work here.
|
||||
|
||||
- name: Reload systemd user units
|
||||
ansible.builtin.command: systemctl --user daemon-reload
|
||||
changed_when: true
|
||||
listen: Reload systemd user units
|
||||
|
||||
# A changed environment file or unit file changes the generated unit, so
|
||||
# Nextcloud is recreated. Nothing is lost by that: config.php, data/ and
|
||||
# custom_apps/ are on the bind mount and the database is in Postgres. It is still
|
||||
# a few seconds of downtime for the site, and the entrypoint re-runs its version
|
||||
# check — including `occ upgrade` if the image has moved on — on the way back up.
|
||||
# Config, data, and custom_apps are on the bind mount, and the database is in Postgres.
|
||||
# The entrypoint reruns its version check, including occ upgrade, on the way back up.
|
||||
- name: Restart Nextcloud
|
||||
ansible.builtin.systemd_service:
|
||||
name: "{{ unit_name }}"
|
||||
|
||||
@@ -1,14 +1,4 @@
|
||||
---
|
||||
# Nextcloud as a rootless Podman Quadlet unit.
|
||||
#
|
||||
# Everything runs as the connection user; requires gather_facts (set in
|
||||
# playbook.yml), which is where podman_user and the home directory come from.
|
||||
#
|
||||
# A fresh webroot is a valid state. The image initialises the code and serves the
|
||||
# setup wizard, and this play succeeds. Set nextcloud_admin_user and
|
||||
# nextcloud_admin_password in vars/default.yml to have it installed unattended
|
||||
# instead.
|
||||
|
||||
- name: Ensure the webroot exists
|
||||
ansible.builtin.file:
|
||||
path: "{{ host_directory }}"
|
||||
@@ -17,9 +7,7 @@
|
||||
group: "{{ podman_user }}"
|
||||
mode: '0755'
|
||||
|
||||
# Read by the entrypoint, not by Ansible, so it has to exist before the unit
|
||||
# starts. Mode 0600: POSTGRES_PASSWORD is in it, and the unit file is
|
||||
# world-readable.
|
||||
# The entrypoint reads this before the unit starts, and POSTGRES_PASSWORD means it stays 0600.
|
||||
- name: Write the environment file
|
||||
ansible.builtin.template:
|
||||
src: nextcloud.env.j2
|
||||
@@ -40,8 +28,7 @@
|
||||
- Reload systemd user units
|
||||
- Restart Nextcloud
|
||||
|
||||
# Quadlet applies [Install] WantedBy= when it generates the unit, so a generated
|
||||
# unit is never `systemctl enable`d.
|
||||
# Quadlet applies [Install] WantedBy= when it generates the unit, so it is never enabled.
|
||||
- name: Start Nextcloud and wait for it to serve
|
||||
block:
|
||||
- name: Start Nextcloud
|
||||
@@ -51,13 +38,8 @@
|
||||
state: started
|
||||
daemon_reload: true
|
||||
|
||||
# `systemctl start` returns while the unit is still `activating`, and a
|
||||
# crash-looping container is `activating` most of the time as well, so
|
||||
# is-active proves nothing. status.php is Nextcloud's own endpoint: it answers
|
||||
# only once the entrypoint has finished (including any `occ upgrade`) and
|
||||
# Apache is up, it reports `installed` either way — so one gate fits both a
|
||||
# fresh webroot and an update — and `maintenance` is in it too, because a
|
||||
# maintenance-mode 503 on every page is otherwise invisible to a probe.
|
||||
# `systemctl start` returns while the unit is still activating, and a crash loop looks the same.
|
||||
# status.php answers after the entrypoint and Apache are ready, and it reports maintenance mode.
|
||||
- name: Wait for Nextcloud to serve status.php
|
||||
ansible.builtin.command: >-
|
||||
podman exec {{ container_name }} php -r
|
||||
@@ -70,8 +52,7 @@
|
||||
delay: 5
|
||||
changed_when: false
|
||||
rescue:
|
||||
# systemd reports "control process exited with error code" and nothing else.
|
||||
# The reason is in the entrypoint's own output.
|
||||
# systemd only reports "control process exited with error code", so read the entrypoint output.
|
||||
- name: Collect diagnostics
|
||||
ansible.builtin.command: "{{ item }}"
|
||||
loop:
|
||||
@@ -94,11 +75,8 @@
|
||||
this playbook has produced before. If the unit is in the `failed` state
|
||||
from an earlier attempt: systemctl --user reset-failed {{ unit_name }}
|
||||
|
||||
# Nextcloud wants `cron.php` every five minutes. This has to be *this user's*
|
||||
# crontab, not root's: root cannot `podman exec` into another user's rootless
|
||||
# containers. It works without any environment plumbing because the caddy
|
||||
# playbook enables lingering, so /run/user/<uid> exists whether or not anyone is
|
||||
# logged in — which is where podman keeps the state `exec` needs.
|
||||
# This must be the connection user's crontab. Root cannot podman exec into another user's rootless containers.
|
||||
# Lingering keeps /run/user/<uid> present, which is where podman keeps the state exec needs.
|
||||
- name: Schedule Nextcloud's background jobs
|
||||
ansible.builtin.cron:
|
||||
name: Nextcloud background jobs
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
---
|
||||
# Postgres is its own playbook (postgres/playbook.yml) and a rootless Quadlet
|
||||
# unit there. This handler runs as the connection user, which is what makes
|
||||
# `systemctl --user` work here.
|
||||
#
|
||||
# Required by postgres/roles/attach, which notifies it whenever this app's
|
||||
# drop-in changes: a new drop-in changes the generated unit, so Postgres must be
|
||||
# recreated to join the network — Quadlet has no live equivalent of
|
||||
# `podman network connect`. That is a few seconds of downtime for every attached
|
||||
# app, not just this one. See postgres/readme.md, "The trade-off".
|
||||
# A new drop-in changes the generated unit, so Postgres is recreated and every attached app restarts.
|
||||
- name: Restart Postgres
|
||||
ansible.builtin.systemd_service:
|
||||
name: "{{ postgres_unit }}"
|
||||
|
||||
@@ -1,21 +1,12 @@
|
||||
---
|
||||
# Attach this app's network to the shared Postgres unit, and make sure the
|
||||
# database exists.
|
||||
|
||||
- name: Attach Nextcloud to Postgres
|
||||
ansible.builtin.include_tasks: "{{ playbook_dir }}/../postgres/roles/attach/tasks/main.yaml"
|
||||
|
||||
# The restart that joins Postgres to nextcloud_net is a handler, so by default it
|
||||
# would run at the end of the play — after the app has started and failed to
|
||||
# resolve `db`. Flushing first also applies the Caddy restart queued by the
|
||||
# register pre_task. Nothing is pending on later runs.
|
||||
# The restart that joins Postgres to nextcloud_net is a handler, so flush it before the app starts. This also applies the queued Caddy restart.
|
||||
- name: Apply the network change before starting Nextcloud
|
||||
ansible.builtin.meta: flush_handlers
|
||||
|
||||
# Postgres ships one default database and only this app knows the name of its own,
|
||||
# so on a fresh cluster the installer would otherwise fail with "database
|
||||
# nextcloud does not exist". The retry is for the restart the flush above may have
|
||||
# just done.
|
||||
# On a fresh cluster the installer would fail without this database, and the retry covers the restart the flush did.
|
||||
- name: Check whether the {{ pg_database }} database exists
|
||||
ansible.builtin.command: >-
|
||||
podman exec -e PGPASSWORD={{ pg_password }} {{ postgres_container }}
|
||||
|
||||
@@ -1,18 +1,6 @@
|
||||
---
|
||||
# Valkey is its own playbook (valkey/playbook.yml) and a rootless Quadlet unit
|
||||
# there. This handler runs as the connection user, which is what makes
|
||||
# `systemctl --user` work here.
|
||||
#
|
||||
# Required by valkey/roles/attach, which notifies it whenever this app's drop-in
|
||||
# changes: a new drop-in changes the generated unit, so Valkey must be recreated
|
||||
# to join the network — Quadlet has no live equivalent of
|
||||
# `podman network connect`.
|
||||
#
|
||||
# Data survives the recreate: RDB persistence is on by default, the stop is
|
||||
# graceful, and the new container loads the snapshot back off the bind mount. What
|
||||
# does not survive is availability — for the seconds the container is down,
|
||||
# Nextcloud's PHP sessions and `memcache.locking` are unreachable. See
|
||||
# valkey/readme.md, "The trade-off".
|
||||
# A new drop-in changes the generated unit, so Valkey is recreated to join the network.
|
||||
# Data survives the recreate, but Nextcloud's cache and locks are unavailable for the seconds it is down.
|
||||
- name: Restart Valkey
|
||||
ansible.builtin.systemd_service:
|
||||
name: "{{ valkey_unit }}"
|
||||
|
||||
@@ -1,28 +1,8 @@
|
||||
---
|
||||
# Attach this app's network to the shared Valkey unit.
|
||||
#
|
||||
# Valkey knows nothing about its clients, exactly like Caddy and Postgres: a
|
||||
# service joins by dropping 50-nextcloud.conf and the shared
|
||||
# 10-network-aliases.conf next to valkey.container. The canonical way to do that
|
||||
# is the shared include below — it writes the same bytes every service writes,
|
||||
# asserts that nextcloud.network already exists, and notifies the "Restart
|
||||
# Valkey" handler defined in this role.
|
||||
#
|
||||
# `redis` is the alias the app connects to, not the container name: it is the host
|
||||
# an instance configured for Redis has in config.php. This playbook does not write
|
||||
# that configuration, it only makes the name resolvable.
|
||||
|
||||
# The app connects to `redis`, the alias the attach role adds, not the container name.
|
||||
- name: Attach Nextcloud to Valkey
|
||||
ansible.builtin.include_tasks: "{{ playbook_dir }}/../valkey/roles/attach/tasks/main.yaml"
|
||||
|
||||
# On a first attach the drop-in is new, so Valkey has to be recreated to join
|
||||
# nextcloud_net — and that restart is a *handler*, which by default runs at the
|
||||
# end of the play, after the nextcloud role has already started the app. The app
|
||||
# would then come up before `redis` resolves; with `memcache.locking` on Redis it
|
||||
# would fail on the first write rather than at startup, which is a worse failure
|
||||
# to debug.
|
||||
#
|
||||
# Flushing applies the new drop-in before the app starts. On later runs the
|
||||
# drop-in is unchanged, nothing is pending, and this is a no-op.
|
||||
# The restart that joins Valkey to nextcloud_net is a handler, so flush it before the app starts or it fails on the first cache write.
|
||||
- name: Apply the Valkey network change before starting Nextcloud
|
||||
ansible.builtin.meta: flush_handlers
|
||||
Reference in new issue
Block a user