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.
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:
#!/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:
#!/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