commit 96c02aafe0a55ae13f1f13c0d0933e8eab53c487 Author: Pau Rodriguez-Estivill Date: Fri Oct 28 14:58:34 2016 +0200 Initial commit. diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a85cc12 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,22 @@ +FROM alpine:3.4 +MAINTAINER Pau Rodriguez-Estivill "prodrigestivill@gmail.com" + +ADD install.sh install.sh +RUN sh install.sh && rm install.sh + +ENV POSTGRES_DATABASE **None** +ENV POSTGRES_HOST **None** +ENV POSTGRES_PORT 5432 +ENV POSTGRES_USER **None** +ENV POSTGRES_PASSWORD **None** +ENV POSTGRES_EXTRA_OPTS '-Z9' +ENV SCHEDULE **None** +ENV BACKUP_DIR '/backups' +ENV BACKUP_KEEP_DAYS 7 +ENV BACKUP_KEEP_WEEKS 4 +ENV BACKUP_KEEP_MONTHS 6 + +ADD run.sh run.sh +ADD backup.sh backup.sh + +CMD ["sh", "run.sh"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..1839c2d --- /dev/null +++ b/README.md @@ -0,0 +1,45 @@ +# postgres-backup-local + +Backup PostgresSQL to local filesystem with periodic backups and rotate backups. +Based on [schickling/postgres-backup-s3](https://hub.docker.com/r/schickling/postgres-backup-s3/). + +## Usage + +Docker: +```sh +$ docker run -e BACKUP_DIR=/backups -e POSTGRES_DATABASE=dbname -e POSTGRES_USER=user -e POSTGRES_PASSWORD=password -e POSTGRES_HOST=localhost schickling/postgres-backup-local +``` + +Docker Compose: +```yaml +postgres: + image: postgres + environment: + POSTGRES_USER: user + POSTGRES_PASSWORD: password + +pgbackups: + image: prodrigestivill/postgres-backup-local + links: + - postgres + volumes: + - /var/opt/pgbackups:/backups + environment: + SCHEDULE: '@daily' + BACKUP_DIR: /backups + BACKUP_KEEP_DAYS: 7 + BACKUP_KEEP_WEEKS: 4 + BACKUP_KEEP_MONTHS: 6 + POSTGRES_DATABASE: dbname + POSTGRES_USER: user + POSTGRES_PASSWORD: password + POSTGRES_EXTRA_OPTS: '-Z9 --schema=public --blobs' +``` + +### Automatic Periodic Backups + +You can additionally set the `SCHEDULE` environment variable like `-e SCHEDULE="@daily"` to run the backup automatically. + +More information about the scheduling can be found [here](http://godoc.org/github.com/robfig/cron#hdr-Predefined_schedules). + +Folders daily, weekly and monthly are created and populated using hard links to save disk space. diff --git a/backup.sh b/backup.sh new file mode 100644 index 0000000..2c22084 --- /dev/null +++ b/backup.sh @@ -0,0 +1,57 @@ +#! /bin/sh + +set -e +set -o pipefail + +if [ "${POSTGRES_DATABASE}" = "**None**" ]; then + echo "You need to set the POSTGRES_DATABASE environment variable." + exit 1 +fi + +if [ "${POSTGRES_HOST}" = "**None**" ]; then + if [ -n "${POSTGRES_PORT_5432_TCP_ADDR}" ]; then + POSTGRES_HOST=$POSTGRES_PORT_5432_TCP_ADDR + POSTGRES_PORT=$POSTGRES_PORT_5432_TCP_PORT + else + echo "You need to set the POSTGRES_HOST environment variable." + exit 1 + fi +fi + +if [ "${POSTGRES_USER}" = "**None**" ]; then + echo "You need to set the POSTGRES_USER environment variable." + exit 1 +fi + +if [ "${POSTGRES_PASSWORD}" = "**None**" ]; then + echo "You need to set the POSTGRES_PASSWORD environment variable or link to a container named POSTGRES." + exit 1 +fi + +#Proces vars +export PGPASSWORD=$POSTGRES_PASSWORD +POSTGRES_HOST_OPTS="-h $POSTGRES_HOST -p $POSTGRES_PORT -U $POSTGRES_USER $POSTGRES_EXTRA_OPTS" +KEEP_DAYS=$BACKUP_KEEP_DAYS +KEEP_WEEKS=`expr $((($BACKUP_KEEP_WEEKS * 7) + 1))` +KEEP_MONTHS=`expr $((($BACKUP_KEEP_MONTHS * 31) + 1))` + +#Initialize filename vers and dirs +DFILE="$BACKUP_DIR/daily/$POSTGRES_DATABASE-`date +%Y%m%d-%H%M%S`.sql.gz" +WFILE="$BACKUP_DIR/weekly/$POSTGRES_DATABASE-`date +%G%V`.sql.gz" +MFILE="$BACKUP_DIR/monthly/$POSTGRES_DATABASE-`date +%Y%m`.sql.gz" +mkdir -p "$BACKUP_DIR/daily/" "$BACKUP_DIR/weekly/" "$BACKUP_DIR/monthly/" + +#Create dump +echo "Creating dump of ${POSTGRES_DATABASE} database from ${POSTGRES_HOST}..." +pg_dump -f "$DFILE" $POSTGRES_HOST_OPTS $POSTGRES_DATABASE + +#Copy (hardlink) for each entry +ln -vf "$DFILE" "$WFILE" +ln -vf "$DFILE" "$MFILE" + +#Clean old files +find "$BACKUP_DIR/daily" -maxdepth 1 -mtime +$KEEP_DAYS -name "$POSTGRES_DATABASE-*.sql*" -exec rm -rf '{}' ';' +find "$BACKUP_DIR/weekly" -maxdepth 1 -mtime +$KEEP_WEEKS -name "$POSTGRES_DATABASE-*.sql*" -exec rm -rf '{}' ';' +find "$BACKUP_DIR/monthly" -maxdepth 1 -mtime +$KEEP_MONTHS -name "$POSTGRES_DATABASE-*.sql*" -exec rm -rf '{}' ';' + +echo "SQL backup uploaded successfully" diff --git a/install.sh b/install.sh new file mode 100644 index 0000000..1578546 --- /dev/null +++ b/install.sh @@ -0,0 +1,18 @@ +#! /bin/sh + +# exit if a command fails +set -e + +apk update + +# install pg_dump +apk add postgresql + +# install go-cron +apk add curl +curl -L https://github.com/odise/go-cron/releases/download/v0.0.6/go-cron-linux.gz | zcat > /usr/local/bin/go-cron +chmod u+x /usr/local/bin/go-cron +apk del curl + +# cleanup +rm -rf /var/cache/apk/* diff --git a/run.sh b/run.sh new file mode 100644 index 0000000..05dfcaa --- /dev/null +++ b/run.sh @@ -0,0 +1,9 @@ +#! /bin/sh + +set -e + +if [ "${SCHEDULE}" = "**None**" ]; then + sh backup.sh +else + exec go-cron "$SCHEDULE" /bin/sh backup.sh +fi