mirror of
https://github.com/zammad/zammad
synced 2026-05-24 09:48:36 +00:00
102 lines
3.2 KiB
Bash
Executable file
102 lines
3.2 KiB
Bash
Executable file
#!/bin/bash
|
|
|
|
set -o errexit
|
|
set -o pipefail
|
|
|
|
: "${BACKUP_DIR:=/var/tmp/zammad}"
|
|
: "${RESTORE_DIR:=/var/tmp/zammad/restore}"
|
|
: "${BACKUP_TIME:=03:00}"
|
|
: "${HOLD_DAYS:=10}"
|
|
|
|
# See DOCKERFILE for environment variables.
|
|
ESCAPED_POSTGRESQL_PASS=$(echo "$POSTGRESQL_PASS" | ruby -ruri -e "puts URI.encode_uri_component(readline.chomp)")
|
|
POSTGRESQL_URL="postgresql://${POSTGRESQL_USER}:${ESCAPED_POSTGRESQL_PASS}@${POSTGRESQL_HOST}:${POSTGRESQL_PORT}/${POSTGRESQL_DB}"
|
|
|
|
function check_zammad_ready {
|
|
echo 'Checking if Zammad is ready...'
|
|
|
|
# Verify that migrations have been ran and seeds executed to process ENV vars like FQDN correctly.
|
|
until bundle exec rails r 'ActiveRecord::Migration.check_all_pending!; Translation.any? || raise' &> /dev/null; do
|
|
echo " waiting for init container to finish install or update..."
|
|
sleep 2
|
|
done
|
|
}
|
|
|
|
function zammad_backup {
|
|
TIMESTAMP="$(date +'%Y%m%d%H%M%S')"
|
|
|
|
echo "${TIMESTAMP} - backing up zammad..."
|
|
|
|
# delete old backups
|
|
if [ -d "${BACKUP_DIR}" ] && [ -n "$(ls "${BACKUP_DIR}")" ]; then
|
|
find "${BACKUP_DIR}" -maxdepth 1 -type f -name "*_zammad_*.gz" -mtime +"${HOLD_DAYS}" -delete
|
|
fi
|
|
|
|
if [ "${NO_FILE_BACKUP}" != "yes" ]; then
|
|
# tar files
|
|
tar -czf "${BACKUP_DIR}"/"${TIMESTAMP}"_zammad_files.tar.gz /opt/zammad/storage
|
|
fi
|
|
|
|
# backup the database
|
|
pg_dump --dbname="${POSTGRESQL_URL}" | gzip > "${BACKUP_DIR}"/"${TIMESTAMP}"_zammad_db.psql.gz
|
|
|
|
echo "backup finished :)"
|
|
}
|
|
|
|
function zammad_backup_loop {
|
|
while true; do
|
|
NOW_TIMESTAMP=$(date +%s)
|
|
TOMORROW_DATE=$(date -d@"$((NOW_TIMESTAMP + 24*60*60))" +%Y-%m-%d)
|
|
|
|
zammad_backup
|
|
|
|
NEXT_TIMESTAMP=$(date -d "$TOMORROW_DATE $BACKUP_TIME" +%s)
|
|
NOW_TIMESTAMP=$(date +%s)
|
|
SLEEP_SECONDS=$((NEXT_TIMESTAMP - NOW_TIMESTAMP))
|
|
|
|
echo "sleeping $SLEEP_SECONDS seconds until the next backup run..."
|
|
|
|
sleep $SLEEP_SECONDS
|
|
done
|
|
}
|
|
|
|
function perform_restore {
|
|
|
|
function call_psql {
|
|
psql --variable ON_ERROR_STOP=1 --quiet --echo-errors --dbname="${POSTGRESQL_URL}"
|
|
}
|
|
|
|
RESTORE_DB_FILE=$(find "${RESTORE_DIR}" -name '*_zammad_db.psql.gz' | sort | tail -n1)
|
|
if [ -z "${RESTORE_DB_FILE}" ]; then
|
|
echo "Error: no database backup found in ${RESTORE_DIR}."
|
|
exit 1
|
|
fi
|
|
echo "Restoring database from ${RESTORE_DB_FILE}…"
|
|
|
|
# Clear the database before restoring.
|
|
echo 'DROP SCHEMA PUBLIC CASCADE; CREATE SCHEMA PUBLIC;' | call_psql
|
|
gunzip -c "${RESTORE_DB_FILE}" | call_psql
|
|
|
|
RESTORE_STORAGE_FILE=$(find "${RESTORE_DIR}" -name '*_zammad_files.tar.gz' | sort | tail -n1)
|
|
if [ -z "${RESTORE_STORAGE_FILE}" ]; then
|
|
echo "No storage backup found in ${RESTORE_DIR}, skipping."
|
|
else
|
|
echo "Restoring storage from ${RESTORE_STORAGE_FILE}…"
|
|
tar -C / --overwrite -xzf "${RESTORE_STORAGE_FILE}" -v opt/zammad/storage
|
|
fi
|
|
|
|
TIMESTAMP="$(date +'%Y%m%d%H%M%S')"
|
|
mv "${RESTORE_DIR}" "${RESTORE_DIR}_completed_${TIMESTAMP}"
|
|
echo "Restore directory was moved to ${RESTORE_DIR}_completed_${TIMESTAMP}. Feel free to delete it."
|
|
|
|
echo "Restore completed."
|
|
}
|
|
|
|
if [ -d "${RESTORE_DIR}" ] && [ -n "$(ls "${RESTORE_DIR}")" ]; then
|
|
echo "Restoring from backup directory ${RESTORE_DIR}…"
|
|
perform_restore
|
|
else
|
|
check_zammad_ready
|
|
echo "Starting backup loop…"
|
|
zammad_backup_loop
|
|
fi
|