Replaces the docker_container playbook, which published 5432 on 0.0.0.0 and kept its data in /var/lib/postgresql. Postgres is now the base Quadlet unit, the same shape as Caddy: it knows nothing about its clients, and a service attaches itself by dropping a file into postgres.container.d/ via postgres/roles/attach. Nothing here changes when a service is added or removed. Pinned to 18, which is two decisions rather than one tag. Postgres 18 moved both the image's VOLUME (/var/lib/postgresql/data -> /var/lib/postgresql) and its default PGDATA (/var/lib/postgresql/data/pgdata -> /var/lib/postgresql/18/docker), and the 18 entrypoint refuses to start when it finds a cluster in the old layout. So postgres_major is the single knob: it picks the image tag and the PGDATA path together, and the mount is now the parent directory. That also settles the migration: a PGDATA copy cannot cross a major version, so monoco's 17.5 cluster comes across as a pg_dumpall. Three things that bit us and are worth keeping: - PGDATA and its version directory are created by the role, not left to the container. The entrypoint runs as container-root, which under keep-id is a subuid on the host, and it only chowns PGDATA and its contents -- so ~/podman-data/postgres/18 would have been stranded subuid-owned, and the host user could not even rm -rf it without podman unshare. - NetworkAlias= applies to every network the container joins, which is what a database hub wants, but it is one fixed value in a shared drop-in rather than per-service: two services writing their own would make Quadlet pass --network-alias twice. It is not in postgres.container itself because on a fresh host that unit has no Network= at all. - The credentials live in a 0600 file read with EnvironmentFile=, not in Environment= lines: the unit is world-readable in ~/.config. The play no longer uses become, and does not apply the rootless-Podman prerequisites -- those are the shared task file at caddy/roles/podman, and the three variables they need are duplicated at the top of vars/default.yml. migrate-from-monoco.md records the one-time 17.5 -> 18.6 move: the dump, transfer and restore commands, the checks that prove the restore is complete (per-database table counts against the source), and the verified result. The dead nginx/php-fpm templates in postgres/files/ are removed.
94 lines
4.2 KiB
YAML
94 lines
4.2 KiB
YAML
---
|
|
# Attach a service's network to Postgres.
|
|
#
|
|
# Postgres is the *base* unit and knows nothing about its clients, the same way
|
|
# Caddy knows nothing about its upstreams. A service that needs a database adds
|
|
# itself by dropping files next to postgres.container, and Quadlet merges them in.
|
|
#
|
|
# Include this from a service playbook:
|
|
#
|
|
# - name: Attach this service to Postgres
|
|
# ansible.builtin.include_tasks: "{{ playbook_dir }}/../postgres/roles/attach/tasks/main.yaml"
|
|
# vars:
|
|
# network_name: "{{ network_name }}"
|
|
#
|
|
# The including play must:
|
|
#
|
|
# 1. have created {{ network_name }}.network already — caddy/roles/register
|
|
# does that, and every service here that needs a database is also behind
|
|
# Caddy, so its register include comes first;
|
|
# 2. run the `podman` role (or include its task file and define the same four
|
|
# vars), for podman_user and quadlet_dir;
|
|
# 3. define a "Restart Postgres" handler — see
|
|
# roles/postgres/handlers/main.yaml for the exact snippet; and
|
|
# 4. flush handlers before starting the app, on a first attach. This include
|
|
# notifies that restart, so by default it runs at the end of the play —
|
|
# after the app has already started and failed to resolve `db`. A
|
|
# `meta: flush_handlers` immediately after this include is enough; see
|
|
# tandoor/roles/postgres for the working example.
|
|
#
|
|
# It runs as the connection user, which must be the rootless podman_user.
|
|
#
|
|
# A service may instead write these two files from its own role; the bytes have
|
|
# to match this file exactly, or the two will overwrite each other on every run.
|
|
|
|
- name: "Check that the {{ network_name }} network unit exists"
|
|
ansible.builtin.stat:
|
|
path: "{{ quadlet_dir }}/{{ network_name }}.network"
|
|
register: postgres_attach_network
|
|
|
|
# A drop-in naming a .network file that does not exist makes Quadlet fail to
|
|
# generate the whole postgres unit, with a message that does not mention the
|
|
# drop-in at all. Fail here instead, where the cause is obvious.
|
|
- name: "Fail if {{ network_name }} has no network unit"
|
|
ansible.builtin.assert:
|
|
that: postgres_attach_network.stat.exists
|
|
fail_msg: >-
|
|
{{ quadlet_dir }}/{{ network_name }}.network does not exist, so attaching
|
|
it to Postgres would break the postgres unit. Create the network first
|
|
(caddy/roles/register does it), then include this file.
|
|
|
|
- name: Ensure the Postgres Quadlet drop-in directory exists
|
|
ansible.builtin.file:
|
|
path: "{{ quadlet_dir }}/{{ postgres_container | default('postgres') }}.container.d"
|
|
state: directory
|
|
owner: "{{ podman_user }}"
|
|
group: "{{ podman_user }}"
|
|
mode: '0755'
|
|
|
|
- name: "Attach {{ network_name }} to Postgres"
|
|
ansible.builtin.copy:
|
|
dest: >-
|
|
{{ quadlet_dir }}/{{ postgres_container | default('postgres') }}.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.
|
|
#
|
|
# Deleting this file removes the network from {{ postgres_container | default('postgres') }} on
|
|
# the next daemon-reload; nothing else changes.
|
|
[Container]
|
|
Network={{ network_name }}.network
|
|
notify: Restart Postgres
|
|
|
|
# NetworkAlias= applies to every network the container joins, which is exactly
|
|
# right for a hub: every app in this repo reaches postgres as `db` (nextcloud,
|
|
# gitea, tandoor and outline use the alias; the rest use the container name).
|
|
# It is a fixed value in one shared file, not a per-service option, so the same
|
|
# bytes are written no matter how many services attach — two services writing
|
|
# their own aliases would make Quadlet pass --network-alias twice.
|
|
- name: "Give {{ postgres_container | default('postgres') }} the shared 'db' alias"
|
|
ansible.builtin.copy:
|
|
dest: >-
|
|
{{ quadlet_dir }}/{{ postgres_container | default('postgres') }}.container.d/10-network-aliases.conf
|
|
owner: "{{ podman_user }}"
|
|
group: "{{ podman_user }}"
|
|
mode: '0644'
|
|
content: |
|
|
# Shared container aliases for {{ postgres_container | default('postgres') }}.
|
|
# Managed by Ansible (the service playbooks that use it). Do not edit.
|
|
[Container]
|
|
NetworkAlias=db
|
|
notify: Restart Postgres
|