e922f5f3b9
CI / changes (pull_request) Successful in 4s
CI / unit (pull_request) Successful in 12s
CI / integration (pull_request) Successful in 24s
CI / ui (pull_request) Successful in 1m9s
CI / conformance (pull_request) Successful in 10s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m41s
Add pgBackRest-based PITR for the production database, shipped disarmed (archive_mode and the base-backup timer gated off) so it stays inert until the operator arms it before real payments — an un-armed deploy cannot pile WAL onto the disk. - Postgres now builds from a thin image carrying pgBackRest (archive_command runs in-process); the prod overlay wires an encrypted (AES-256-CBC), path-style S3 repository with 30-day retention and a daily full base-backup systemd timer. - Repository config/secrets flow through the PROD_PGBACKREST_* Gitea set and write-prod-env.sh; prod-rollback re-renders the same env so a rollback cannot disarm archiving. - Grafana alerts watch pg_stat_archiver (failing / stalled), absent-safe on the test contour, which never archives. - Fix the pre-migration pg_dump to snapshot the whole database (was backend-only, silently excluding payments). - Document the PITR runbook, the arming sequence and the restore drill in deploy/README.md; record the measured cost/perf assessment.
46 lines
1.6 KiB
YAML
46 lines
1.6 KiB
YAML
---
|
|
# Main stack host: public web + bot-link ports and the external 'edge' network
|
|
# the compose stack attaches caddy to.
|
|
|
|
- name: Open public web and bot-link ports
|
|
community.general.ufw:
|
|
rule: allow
|
|
port: "{{ item }}"
|
|
proto: tcp
|
|
loop:
|
|
- "80" # HTTP (ACME challenge + redirect to HTTPS)
|
|
- "443" # HTTPS (caddy edge)
|
|
- "9443" # bot-link mTLS (remote bot dials in; mutual TLS gates access)
|
|
|
|
- name: Ensure the external 'edge' docker network exists
|
|
community.docker.docker_network:
|
|
name: edge
|
|
state: present
|
|
|
|
# --- pgBackRest base-backup schedule (point-in-time recovery) ------------------
|
|
# A daily full base backup via a systemd timer that runs pgBackRest inside the postgres
|
|
# container; archive_command handles the continuous WAL between backups. Gated by
|
|
# pitr_enabled so the schedule stays inert until archiving is armed (the S3 repository +
|
|
# stanza must exist first, or the run fails nightly). Arm per deploy/README.md.
|
|
- name: Install the pgBackRest base-backup service
|
|
ansible.builtin.template:
|
|
src: pgbackrest-backup.service.j2
|
|
dest: /etc/systemd/system/pgbackrest-backup.service
|
|
mode: "0644"
|
|
when: pitr_enabled | default(false) | bool
|
|
|
|
- name: Install the pgBackRest base-backup timer
|
|
ansible.builtin.template:
|
|
src: pgbackrest-backup.timer.j2
|
|
dest: /etc/systemd/system/pgbackrest-backup.timer
|
|
mode: "0644"
|
|
when: pitr_enabled | default(false) | bool
|
|
|
|
- name: Enable and start the pgBackRest base-backup timer
|
|
ansible.builtin.systemd:
|
|
name: pgbackrest-backup.timer
|
|
enabled: true
|
|
state: started
|
|
daemon_reload: true
|
|
when: pitr_enabled | default(false) | bool
|