Skip to content

DB Dumps Scripts

Konfiguracja

Skrypty służą do wykonywania dumpów baz danych uruchomionych w Dockerze oraz do utrzymania retencji lokalnych katalogów backupu.

Założenia konfiguracyjne:

  • Skrypty znajdują się w /srv/config/scripts/.
  • Backupy zapisywane są w /srv/backups/db-dumps/.
  • Sekrety i zmienne środowiskowe wymagane przez skrypty znajdują się w pliku db-backup.env
  • Logi skryptów trafiają na stdout/stderr

Wymagany skrypt wspólny

Wymagany skrypt backup-common.sh

Aby skrypty dump się wykonały wymagane jest, aby w tym samym folderze znajdował się skrypt backup-common.sh, który zawiera funkcje współdzielone przez wszystkie skrypty backup.

backup-common.sh


Skrypt dump Postgres

Skrypt wykonuje logiczny dump baz PostgreSQL działających w kontenerze.

Tworzymy plik:

micro /srv/config/scripts/backup-db-postgres.sh

W pliku umieszczamy:

backup-db-postgres.sh
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
umask 077

# 1. Load Common Library (robust path)
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
LIB_FILE="${SCRIPT_DIR}/backup-common.sh"

if [[ ! -f "${LIB_FILE}" ]]; then
  echo "CRITICAL: Library ${LIB_FILE} not found." >&2
  exit 1
fi

# shellcheck disable=SC1090
source "${LIB_FILE}"


# 2. Configuration
BACKUP_NAME="postgres"
OUT_BASE_DIR="/srv/backups/db-dumps/postgres"
TS="$(date +%Y%m%d_%H%M)"
FINAL_OUT_DIR="${OUT_BASE_DIR}/${TS}"
ENV_FILE="/srv/backups/restic/db-backup.env"
RETENTION_DAYS=14

# 3. Standard Checks & Setup (from Common)
acquire_lock "backup-db-${BACKUP_NAME}"
check_root
check_config_perms "${ENV_FILE}"
setup_backup_env "${FINAL_OUT_DIR}"

# 4. Load & Validate Env
set -a
source "${ENV_FILE}"
set +a

: "${POSTGRES_CONTAINER:?POSTGRES_CONTAINER is missing in env file}"
: "${POSTGRES_USER:?POSTGRES_USER is missing in env file}"

# 5. Logic
header "Starting PostgreSQL Backup: ${TS}"

# Ensure correct context
cd /srv/docker/database/postgres
CID="$(docker compose ps -q "${POSTGRES_CONTAINER}")"

if [[ -z "${CID}" ]]; then
    critical "Container ${POSTGRES_CONTAINER} is not running."
fi

OK=0
FAIL=0

# --- Helper Function ---
dump_db() {
    local db="$1"
    local out="$2"
    local err="${out}.err"

    # Flags preserved from original:
    # -Fc: Custom binary format
    # --no-owner: Skips setting ownership
    # -x: Skips privileges
    if docker exec "${CID}" sh -c "pg_dump -U \"${POSTGRES_USER}\" -Fc --no-owner -x \"${db}\"" \
        > "${out}" 2> "${err}"; then

        [[ -s "${err}" ]] || rm -f "${err}"
        return 0
    else
        [[ -s "${err}" ]] || rm -f "${err}"
        return 1
    fi
}

# --- 1. DUMP GLOBALS ---
header "Dumping Globals"
log "Exporting roles, groups, permissions..."

# Flags preserved: --globals-only
if docker exec "${CID}" sh -c "export PGDATABASE=postgres; pg_dumpall --globals-only -U \"${POSTGRES_USER}\"" \
    > "${FINAL_OUT_DIR}/globals.sql" 2> "${FINAL_OUT_DIR}/globals.err"; then

    [[ -s "${FINAL_OUT_DIR}/globals.err" ]] || rm -f "${FINAL_OUT_DIR}/globals.err"
    log "Globals exported successfully."
else
    error "Globals dump failed (Check ${FINAL_OUT_DIR}/globals.err)"
    FAIL=$((FAIL+1))
fi

# --- 2. RETRIEVE DATABASE LIST ---
header "Fetching Database List"
# Query preserved: filters templates and 'postgres' db
DB_LIST="$(docker exec "${CID}" sh -c "export PGDATABASE=postgres; psql -U \"${POSTGRES_USER}\" -Atc \"SELECT datname FROM pg_database WHERE datistemplate = false AND datname <> 'postgres' ORDER BY datname;\"" | tr -d '\r')"

# Save list for audit
printf '%s\n' "${DB_LIST}" > "${FINAL_OUT_DIR}/db_list.txt"

# --- 3. DUMP INDIVIDUAL DATABASES ---
while read -r db; do
    [[ -z "${db}" ]] && continue

    if dump_db "${db}" "${FINAL_OUT_DIR}/${db}.dump"; then
      echo "  + Dumped: ${db}"
      OK=$((OK+1))
    else
      echo -e "${RED}  ! Failed: ${db} (see ${FINAL_OUT_DIR}/${db}.dump.err)${NC}" >&2
      FAIL=$((FAIL+1))
    fi
done <<< "${DB_LIST}"

# --- 4. RETENTION & FINISH ---
perform_retention "${OUT_BASE_DIR}" "${RETENTION_DAYS}"

# Finish
finish_backup "${FINAL_OUT_DIR}" "$FAIL"

Nadawanie uprawnień

Uprawnienia 0750 pozwalają uruchamiać skrypt tylko rootowi i zaufanej grupie (np. sudo), a jednocześnie blokują dostęp dla pozostałych użytkowników.

sudo chown root:root /srv/config/scripts/backup-db-postgres.sh
sudo chmod 0750 /srv/config/scripts/backup-db-postgres.sh

Skrypt dump MariaDB

Skrypt wykonuje logiczny dump baz MariaDB działających w kontenerze.

Tworzymy plik:

micro /srv/config/scripts/backup-db-mariadb.sh

W pliku umieszczamy:

backup-db-mariadb.sh
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
umask 077

# 1. Load Common Library (robust path)
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
LIB_FILE="${SCRIPT_DIR}/backup-common.sh"

if [[ ! -f "${LIB_FILE}" ]]; then
    echo "CRITICAL: Library ${LIB_FILE} not found." >&2
    exit 1
fi

# shellcheck disable=SC1090
source "${LIB_FILE}"

# 2. Configuration
BACKUP_NAME="mariadb"
OUT_BASE_DIR="/srv/backups/db-dumps/mariadb"
TS="$(date +%Y%m%d_%H%M)"
FINAL_OUT_DIR="${OUT_BASE_DIR}/${TS}"
ENV_FILE="/srv/backups/restic/db-backup.env"
RETENTION_DAYS=14

# 3. Standard Checks & Setup (from Common)
acquire_lock "backup-db-${BACKUP_NAME}"
check_root
check_config_perms "${ENV_FILE}"
setup_backup_env "${FINAL_OUT_DIR}"

# 4. Load & Validate Env
set -a
source "${ENV_FILE}"
set +a

: "${MARIADB_CONTAINER:?Variable missing}"
: "${MARIADB_ROOT_PASSWORD:?Variable missing}"

# 5. Logic
header "Starting MariaDB Backup: ${TS}"

cd /srv/docker/database/mariadb
CID="$(docker compose ps -q "${MARIADB_CONTAINER}")"
[[ -z "${CID}" ]] && critical "Container ${MARIADB_CONTAINER} not running."

OK=0
FAIL=0

dump_db() {
    local db="$1"
    local out="$2"
    local err="${out}.err"

    if docker exec -e "MYSQL_PWD=${MARIADB_ROOT_PASSWORD}" "${CID}" \
        mariadb-dump \
        --single-transaction \
        --skip-lock-tables \
        --quick \
        --skip-comments \
        --routines \
        --events \
        --triggers \
        --hex-blob \
        -uroot \
        "${db}" \
        > "${out}" 2> "${err}"; then

        [[ -s "${err}" ]] || rm -f "${err}"
        return 0
    else
        [[ -s "${err}" ]] || rm -f "${err}"
        return 1
    fi
}

# --- System DB ---
log "Dumping system database (mysql)..."
if dump_db "mysql" "${FINAL_OUT_DIR}/mysql_system.sql"; then
    OK=$((OK+1))
else
    error "Failed: System Database"
    FAIL=$((FAIL+1))
fi

# --- User DBs ---
log "Fetching database list..."
DBS="$(docker exec -e "MYSQL_PWD=${MARIADB_ROOT_PASSWORD}" "${CID}" mariadb -uroot -N -e "SHOW DATABASES;" | tr -d '\r')"
echo "$DBS" > "${FINAL_OUT_DIR}/db_list.txt"

while read -r db; do
    [[ -z "${db}" ]] && continue
    [[ "$db" =~ ^(information_schema|performance_schema|sys|mysql)$ ]] && continue

    if dump_db "${db}" "${FINAL_OUT_DIR}/${db}.sql"; then
      echo "  + Dumped: ${db}"
      OK=$((OK+1))
    else
      echo -e "${RED}  ! Failed: ${db} (see ${FINAL_OUT_DIR}/${db}.sql.err)${NC}" >&2
      FAIL=$((FAIL+1))
    fi
done <<< "$DBS"

# 6. Retention & Finish
perform_retention "${OUT_BASE_DIR}" "${RETENTION_DAYS}"

finish_backup "${FINAL_OUT_DIR}" "$FAIL"

Nadawanie uprawnień

Uprawnienia 0750 pozwalają uruchamiać skrypt tylko rootowi i zaufanej grupie (np. sudo), a jednocześnie blokują dostęp dla pozostałych użytkowników.

sudo chown root:root /srv/config/scripts/backup-db-mariadb.sh
sudo chmod 0750 /srv/config/scripts/backup-db-mariadb.sh