#!/bin/bash # Backup Vaultwarden database in a Kubernetes environment. # Usage: backup-database [OPTIONS] usage() { >&2 printf "Usage: %s \n" "${0}" >&2 printf "Options:\n" >&2 printf "\t-e \t Specify the environment file to use\n" exit "${1:-1}" } # Get options while getopts ":e:" option; do case "${option}" in e) if ! [ -f "${OPTARG}" ]; then >&2 printf "Error: Specified environment file does not exist: '%s'.\n" "${OPTARG}" elif ! [ -r "${OPTARG}" ]; then >&2 printf "Error: Specified environment file is not readable: '%s'.\n" "${OPTARG}" fi env_file="${OPTARG}" ;; *) >&2 printf "Error: Invalid option: '%s'.\n" "${option}" usage ;; esac done shift $(( OPTIND - 1 )) # Check arguments if [ $# -ne 1 ]; then >&2 printf "Error: You need to specify a destination.\n" usage elif ! [ -d "${1}" ]; then >&2 printf "Error: Specified destination does not exist or is not readable : '%s'.\n" "${1}" usage else destination="${1}" fi namespace="ix-vaultwarden-2" # Retrieve container names base_container="$( k3s kubectl get pods --namespace "${namespace}" | cut -f1 -d' ' | grep -E 'vaultwarden-2-[0-9a-z]{10}-[0-9a-z]{5}' )" database_container="$( k3s kubectl get pods --namespace "${namespace}" | cut -f1 -d' ' | grep 'vaultwarden-2-cnpg-main-1' )" if ! [[ -n "${base_container}" && -n "${database_container}" ]]; then >&2 printf "Error: Not all containers could be found.\n" exit 2 fi # Abort entire script if any command fails set -e # Database backup # Filename for database backup database_backupfile="vaultwarden-sqlbkp_$(date +'%Y%m%d').bak" host_database_backupfile="${destination}/${database_backupfile}" # Create backup file in Kubernetes pod echo 'Backing up database' k3s kubectl exec "${database_container}" --namespace "${namespace}" -- env $(cat "${env_file:=.env}" | xargs) pg_dump 'vaultwarden' -cwv -h 'localhost' -U 'vaultwarden' > "${host_database_backupfile}" # Files backup for file in 'attachments' 'sends' 'rsa_key.pem' 'rsa_key.pub.pem'; do # 'config.json' printf 'Copying %s\n' "${file}" k3s kubectl --namespace "${namespace}" cp "${base_container}":"/data/${file}" "${destination}" done # Backup cleanup # Only keep 30 days of backups, seems about right. echo 'Cleaning up old database backups' find "${destination}" -name '*sqlbkp*' -type f -mtime +30 -print -delete echo 'Done'