From 2eba95eb41d699eb5396ae776bb6ae3753a95dfc Mon Sep 17 00:00:00 2001 From: Nicolas MASSE Date: Sat, 29 Nov 2025 22:10:22 +0100 Subject: [PATCH] postgresql backup --- postgresql/Makefile | 9 +++-- postgresql/config/backup.sh | 19 ++++++++++ postgresql/postgresql-backup.container | 46 +++++++++++++++++++++++++ postgresql/postgresql-init.container | 5 +-- postgresql/postgresql-server.container | 9 +++++ postgresql/postgresql-upgrade.container | 3 ++ postgresql/postgresql.pod | 17 +++++++++ postgresql/postgresql.target | 4 +-- 8 files changed, 106 insertions(+), 6 deletions(-) create mode 100755 postgresql/config/backup.sh create mode 100644 postgresql/postgresql-backup.container create mode 100644 postgresql/postgresql.pod diff --git a/postgresql/Makefile b/postgresql/Makefile index 9dd1ec6..443bb2b 100644 --- a/postgresql/Makefile +++ b/postgresql/Makefile @@ -48,7 +48,12 @@ dryrun: install -D -m 0644 -o root -g root $< $@ /etc/quadlets/$(PROJECT_NAME)/%: config/% - install -D -m 0644 -o root -g root $< $@ + @run() { echo $$*; "$$@"; }; \ + if [ -x $< ]; then \ + run install -D -m 0755 -o root -g root $< $@; \ + else \ + run install -D -m 0644 -o root -g root $< $@; \ + fi install: pre-requisites dryrun $(TARGET_QUADLETS_FILES) $(TARGET_SYSTEMD_FILES) $(TARGET_CONFIG_FILES) systemctl daemon-reload @@ -63,4 +68,4 @@ uninstall: pre-requisites systemctl daemon-reload clean: - rm -rf /var/lib/quadlets/$(PROJECT_NAME)/ /etc/quadlets/$(PROJECT_NAME)/ + rm -rf /var/lib/quadlets/$(PROJECT_NAME)/ /var/run/quadlets/$(PROJECT_NAME)/ /etc/quadlets/$(PROJECT_NAME)/ diff --git a/postgresql/config/backup.sh b/postgresql/config/backup.sh new file mode 100755 index 0000000..a4a36a2 --- /dev/null +++ b/postgresql/config/backup.sh @@ -0,0 +1,19 @@ +#!/bin/bash +set -Eeuo pipefail + +export PGHOST=/var/run/postgresql + +BACKUP_DIR=/backup/$(date +%Y%m%d) +mkdir -p "$BACKUP_DIR" + +psql -c "SELECT datname FROM pg_database WHERE datname NOT IN ('template0', 'template1', 'postgres');" -t | while read db; do + if [ -z "$db" ]; then + continue + fi + + echo "Backup of database $db..." + pg_dump -c --if-exists "$db" | gzip -c > "$BACKUP_DIR/dump-$db.sql.gz" +done +echo "Complete backup of the whole PostgreSQL server..." +pg_basebackup -D "$BACKUP_DIR/pg_basebackup" +echo "Backups stored in $BACKUP_DIR" diff --git a/postgresql/postgresql-backup.container b/postgresql/postgresql-backup.container new file mode 100644 index 0000000..043e0b1 --- /dev/null +++ b/postgresql/postgresql-backup.container @@ -0,0 +1,46 @@ +[Unit] +Description=PostgreSQL Database Server - Backup +Documentation=https://hub.docker.com/_/postgres/ +After=network.target postgresql-server.service +Requires=postgresql-server.service + +# Start/stop this unit when the target is started/stopped +PartOf=postgresql.target + +[Container] +ContainerName=postgresql-backup-job +Image=docker.io/library/postgres:${PG_MAJOR}-alpine + +# Network configuration +Network=host + +# Those environment variables will be injected by podman into the container +EnvironmentFile=/etc/quadlets/postgresql/config.env + +# Use a custom backup script +Entrypoint=/usr/local/bin/backup.sh +User=postgres + +# Volume mounts +Volume=/var/lib/quadlets/postgresql:/var/lib/postgresql:z +Volume=/etc/quadlets/postgresql/backup.sh:/usr/local/bin/backup.sh:z,ro + +# This container is part of a Pod +Pod=postgresql.pod + +# Share /var/run/postgresql/ between containers in the pod for the Unix socket +Volume=/var/run/quadlets/postgresql:/var/run/postgresql:z +Volume=/var/lib/quadlets/postgresql/backup:/backup:z + +[Service] +Restart=no +TimeoutStartSec=600 + +# These environment variables are sourced to be used by systemd in the Exec* commands +EnvironmentFile=/etc/quadlets/postgresql/config.env + +# This container is a job - run once to completion +Type=oneshot + +# Skaffold filesystem + fix permissions +ExecStartPre=install -m 0700 -o 70 -g 70 -d /var/lib/quadlets/postgresql/backup diff --git a/postgresql/postgresql-init.container b/postgresql/postgresql-init.container index c6590f5..bc3c495 100644 --- a/postgresql/postgresql-init.container +++ b/postgresql/postgresql-init.container @@ -28,12 +28,13 @@ EnvironmentFile=/etc/quadlets/postgresql/config.env # Use the official entrypoint script to initialize the database Entrypoint=/usr/local/bin/docker-ensure-initdb.sh -# Entrypoint=/bin/sleep -# Exec=INF # Volume mounts Volume=/var/lib/quadlets/postgresql:/var/lib/postgresql:z +# This container is part of a Pod +Pod=postgresql.pod + [Service] Restart=no TimeoutStartSec=30 diff --git a/postgresql/postgresql-server.container b/postgresql/postgresql-server.container index 3266c2f..2ae9384 100644 --- a/postgresql/postgresql-server.container +++ b/postgresql/postgresql-server.container @@ -41,6 +41,12 @@ HealthTimeout=10s HealthStartPeriod=60s HealthRetries=3 +# This container is part of a Pod +Pod=postgresql.pod + +# Share /var/run/postgresql/ between containers in the pod for the Unix socket +Volume=/var/run/quadlets/postgresql:/var/run/postgresql:z + [Service] Restart=always RestartSec=10 @@ -50,5 +56,8 @@ TimeoutStopSec=30 # These environment variables are sourced to be used by systemd in the Exec* commands EnvironmentFile=/etc/quadlets/postgresql/config.env +# Skaffold filesystem + fix permissions +ExecStartPre=install -m 0700 -o 70 -g 70 -d /var/run/quadlets/postgresql + [Install] WantedBy=postgresql.target diff --git a/postgresql/postgresql-upgrade.container b/postgresql/postgresql-upgrade.container index d1f2036..fa63450 100644 --- a/postgresql/postgresql-upgrade.container +++ b/postgresql/postgresql-upgrade.container @@ -32,6 +32,9 @@ EnvironmentFile=/etc/quadlets/postgresql/config.env # Volume mounts Volume=/var/lib/quadlets/postgresql:/var/lib/postgresql:z +# This container is part of a Pod +Pod=postgresql.pod + [Service] Restart=no TimeoutStartSec=600 diff --git a/postgresql/postgresql.pod b/postgresql/postgresql.pod new file mode 100644 index 0000000..dda25c5 --- /dev/null +++ b/postgresql/postgresql.pod @@ -0,0 +1,17 @@ +[Unit] +Description=PostgreSQL Database Server - Pod +Documentation=https://hub.docker.com/_/postgres/ +After=network.target +Before=postgresql.target + +# Only start if PostgreSQL has been configured +ConditionPathExists=/etc/quadlets/postgresql/config.env + +# Start/stop this unit when the target is started/stopped +PartOf=postgresql.target + +[Pod] +PodName=postgresql + +[Install] +WantedBy=postgresql.target diff --git a/postgresql/postgresql.target b/postgresql/postgresql.target index 55f9f2b..50c587d 100644 --- a/postgresql/postgresql.target +++ b/postgresql/postgresql.target @@ -1,8 +1,8 @@ [Unit] Description=PostgreSQL Service Target Documentation=man:systemd.target(5) -Requires=postgresql-server.service postgresql-upgrade.service postgresql-init.service postgresql-set-major.service -After=postgresql-server.service postgresql-upgrade.service postgresql-init.service postgresql-set-major.service +Requires=postgresql-pod.service postgresql-server.service postgresql-upgrade.service postgresql-init.service postgresql-set-major.service +After=postgresql-pod.service postgresql-server.service postgresql-upgrade.service postgresql-init.service postgresql-set-major.service # Allow isolation - can stop/start this target independently AllowIsolate=yes