Ежедневный бэкап Postgres и медиафайлов Django из Docker-контейнеров

Скриптами бэкапов никого не удивить, но даже в этой понятной задаче есть нюансы, которые от проекта к проекту важно не забывать. Делюсь решением для Django-приложения, работающего в среде Docker.

Особенности скрипта:

  • Получает сжатый дамп Postgres и GZIP-архив медиафайлов Django из запущенных контейнеров.
  • Вычищает устаревшие бэкапы по метке проекта.
  • Сохраняет только успешно сформированные бэкапы.

В примере название базы данных и имя пользователя совпадают с названием проекта. Скрипт размещается на хост-машине.

#!/bin/bash
# Author: Eugene Zyatev
# Email: eu@zyatev.ru
# Usage: backup.sh
# Description: Backup data into a daily files.

BACKUP_DIR=/var/lib/myproject/backups
DAYS_TO_KEEP=30
PROJECT=myproject

prune_outdated() {
    find $BACKUP_DIR -maxdepth 1 -mtime +$DAYS_TO_KEEP -name "*${PROJECT}*" -exec rm -rf '{}' ';'
}

backup () {
    cmd=$1
    suffix=$2
    file="${BACKUP_DIR}/"`date +"%Y%m%d%H%M"`"_${PROJECT}_${suffix}"
    tempfile="$(mktemp ${BACKUP_DIR}/.XXXXXXXX)"
    trap "rm -f '$tempfile'; exit 1" 0 1 2 3 13 15

    if ${cmd} > ${tempfile}
    then mv "${tempfile}" "${file}"
    else rm "${tempfile}"
    fi

    trap 0
}

# do the database backup (postgres custom-format archive)
backup "docker exec ${PROJECT}_db_1 pg_dump -U${PROJECT} -h db ${PROJECT} -Fc" "db.dump"
# do the media backup (tarball)
backup "docker exec ${PROJECT}_app_1 tar -C /app/ -zc media" "media.tar.gz"

prune_outdated

Задача для cron:

# m h  dom mon dow   command
0 3 * * * /opt/myproject/backup.sh
# empty line