├── Dockerfile ├── README.md └── bin ├── backup ├── cron-job ├── entrypoint └── restore /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM cusspvz/node:0.12.9 2 | MAINTAINER Fernando Neto 3 | 4 | RUN apk add --update py-pip mysql-client bash apk-cron && \ 5 | pip install awscli && \ 6 | npm install -g slack-cli && \ 7 | rm -fR /var/cache/apk/* 8 | 9 | # this prevent "TERM environment variable not set."" 10 | ENV TERM dumb 11 | 12 | RUN mkdir -p /backup 13 | ADD . /backup 14 | RUN chmod +x /backup/bin/* 15 | 16 | WORKDIR /backup/bin/ 17 | 18 | ENTRYPOINT ["/backup/bin/entrypoint"] 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Docker-mysql-backup-s3 2 | 3 | container to backup and restore your mysql database's to using awscli. 4 | 5 | # Container startup explained 6 | 7 | * This container user cron to make backups 8 | * Mysql will dump the database to this container and compress it using gzip 9 | * Using s3cli the file will be uploaded to S3 Storage 10 | * To restore a db just enter the container and run the 'restore' script with the file name to restore: 11 | 12 | ```bash 13 | ./restore example.sql.gz 14 | ``` 15 | 16 | * To run a manual backup just enter the container and run: 17 | 18 | ```bash 19 | ./backup 20 | ``` 21 | 22 | # Environment variables 23 | 24 | - _`$MYSQL_PASSWORD`_ - The password to connect with Mysql. 25 | - _`$MYSQL_USER`_ - The username to connect with Mysql. 26 | - _`$DB_NAME`_ - Database name. 27 | - _`$AWS_ACCESS_KEY_ID`_ - Aws acess key. 28 | - _`$AWS_SECRET_ACCESS_KEY`_ -Aws secret key. 29 | - _`$BUCKET`_ - Aws bucket name . 30 | - _`$REGION`_ - Aws region where your bucket is. 31 | - _`$MYSQL_PORT`_ - Port to connect with Mysql. default 3306. 32 | - _`$MYSQL_HOST`_ - Host where mysql is running. 33 | - _`$FILENAME`_ - Name to file in Azure Storage. Default name `default-date +"%Y-%m-%d_%H-%M"` output example `default-2015-08-03_17-58` 34 | - _`$BACKUP_WINDOW`_ - What time should backup run. you should use crontab format, so see [documentation](http://www.freebsd.org/cgi/man.cgi?crontab(5). default value every day at 6 am. 35 | - _`$SLACK_TOKEN`_ - Your slack token. 36 | - _`$SLACK_CHANNEL`_ - Slack channel to send message. 37 | 38 | # Example of running 39 | 40 | ```bash 41 | docker run --rm --name mysql-backup \ 42 | --env AWS_ACCESS_KEY_ID=AKIAIDHJDJCCC2KM4SSA \ 43 | --env AWS_SECRET_ACCESS_KEY=HT1PWzBN5sjVPFHCuTX+VQs+8nQ00KteoI44iBfz \ 44 | --env BUCKET=backups.example.com \ 45 | --env REGION=eu-west-1 \ 46 | --env FILENAME=backup \ 47 | --env MYSQL_HOST=test.mysql.net \ 48 | --env MYSQL_USER=root \ 49 | --env MYSQL_PASSWORD=password \ 50 | --env DB_NAME=mysql-db \ 51 | --env BACKUP_WINDOW='0 6 * * *' \ 52 | --env SLACK_TOKEN=abd5682jdj \ 53 | --env SLACK_CHANNEL=slack-group \ 54 | fernandoneto/docker-mysql-backup-s3 55 | 56 | ``` 57 | 58 | This will upload to Aws S3 a file named `default-2015-08-04_09-47.sql.gz`. 59 | 60 | ### Building image 61 | 62 | ```bash 63 | docker build -t fernandoneto/docker-mysql-backup-s3 . 64 | ``` 65 | -------------------------------------------------------------------------------- /bin/backup: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DATETIME=`date +"%Y-%m-%d_%H_%M"` 4 | FILE=$FILENAME-$DATETIME.sql.gz 5 | 6 | mysqldump -h $MYSQL_HOST -P $MYSQL_PORT -u $MYSQL_USER -p$MYSQL_PASSWORD $DB_NAME | gzip -9 -c | aws s3 cp - --region=$REGION s3://$BUCKET/$FILE 7 | 8 | if [ "$?" != "0" ]; then 9 | echo "Error occurred in database backup process. Exiting now" 10 | fi 11 | -------------------------------------------------------------------------------- /bin/cron-job: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DATETIME=`date +"%Y-%m-%d_%H_%M"` 4 | PID=`ps aux | grep "/var/log/cron.log" | grep -v grep | awk '{print $1}'` 5 | 6 | make_backup () { 7 | 8 | AWS_ACCESS_KEY_ID={{AWS_ACCESS_KEY_ID}} 9 | AWS_SECRET_ACCESS_KEY={{AWS_SECRET_ACCESS_KEY}} 10 | BUCKET={{BUCKET}} 11 | REGION={{REGION}} 12 | MYSQL_HOST={{MYSQL_HOST}} 13 | MYSQL_PORT={{MYSQL_PORT}} 14 | MYSQL_USER={{MYSQL_USER}} 15 | MYSQL_PASSWORD={{MYSQL_PASSWORD}} 16 | DB_NAME={{DB_NAME}} 17 | SLACK_TOKEN={{SLACK_TOKEN}} 18 | SLACK_CHANNEL={{SLACK_CHANNEL}} 19 | FILE={{FILENAME}}-$DATETIME.sql.gz 20 | 21 | mysqldump -h $MYSQL_HOST -P $MYSQL_PORT -u $MYSQL_USER -p$MYSQL_PASSWORD $DB_NAME | gzip -9 -c | aws s3 cp - --region=$REGION s3://$BUCKET/$FILE 22 | 23 | # exit if last command have problems 24 | if [ "$?" == "0" ]; then 25 | echo "Backup process complete"; 26 | slackcli -t $SLACK_TOKEN -h $SLACK_CHANNEL -m "Backup completed for $FILENAME" 27 | else 28 | echo "Error occurred in backup process. Exiting now" 29 | slackcli -t $SLACK_TOKEN -h $SLACK_CHANNEL -m "Error occurred in backup process $FILENAME." 30 | kill -9 $PID 31 | fi 32 | 33 | } 34 | 35 | make_backup 36 | -------------------------------------------------------------------------------- /bin/entrypoint: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | MYSQL_PORT=${MYSQL_PORT:-3306} 4 | FILENAME=${FILENAME:-backup} 5 | BACKUP_WINDOW=${BACKUP_WINDOW:-"0 6 * * * "} 6 | 7 | sed 's,{{FILENAME}},'"${FILENAME}"',g' -i /backup/bin/cron-job 8 | sed 's,{{AWS_ACCESS_KEY_ID}},'"${AWS_ACCESS_KEY_ID}"',g' -i /backup/bin/cron-job 9 | sed 's,{{AWS_SECRET_ACCESS_KEY}},'"${AWS_SECRET_ACCESS_KEY}"',g' -i /backup/bin/cron-job 10 | sed 's,{{BUCKET}},'"${BUCKET}"',g' -i /backup/bin/cron-job 11 | sed 's,{{REGION}},'"${REGION}"',g' -i /backup/bin/cron-job 12 | sed 's,{{MYSQL_HOST}},'"${MYSQL_HOST}"',g' -i /backup/bin/cron-job 13 | sed 's,{{MYSQL_PORT}},'"${MYSQL_PORT}"',g' -i /backup/bin/cron-job 14 | sed 's,{{MYSQL_USER}},'"${MYSQL_USER}"',g' -i /backup/bin/cron-job 15 | sed 's,{{MYSQL_PASSWORD}},'"${MYSQL_PASSWORD}"',g' -i /backup/bin/cron-job 16 | sed 's,{{DB_NAME}},'"${DB_NAME}"',g' -i /backup/bin/cron-job 17 | sed 's,{{SLACK_TOKEN}},'"${SLACK_TOKEN}"',g' -i /backup/bin/cron-job 18 | sed 's,{{SLACK_CHANNEL}},'"${SLACK_CHANNEL}"',g' -i /backup/bin/cron-job 19 | 20 | touch /var/log/cron.log; 21 | 22 | # prevent duplicate jobs when restart containers 23 | if [ ! -f /home/.cronjob ]; then 24 | 25 | crontab -l | { cat; echo "$BACKUP_WINDOW /backup/bin/cron-job >> /var/log/cron.log 2>&1"; } | crontab - 26 | touch /home/.cronjob 27 | 28 | fi 29 | 30 | # run cron in background and show the output 31 | crond; 32 | tail -f /var/log/cron.log; 33 | -------------------------------------------------------------------------------- /bin/restore: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "$1" == "" ]; then 4 | echo "You did not choose any file to download;" 5 | echo "EX: ./restore backup-201501.sql.gz" 6 | fi 7 | 8 | # Create database and grant permissions 9 | echo "DROP DATABASE IF EXISTS ${DB_NAME}; CREATE DATABASE ${DB_NAME}; GRANT ALL PRIVILEGES ON *.* TO '${MYSQL_USER}'@'%' IDENTIFIED BY '${MYSQL_PASSWORD}' WITH GRANT OPTION; FLUSH PRIVILEGES;" | mysql -h $MYSQL_HOST --port=$MYSQL_PORT -u ''"$MYSQL_USER"'' --password=$MYSQL_PASSWORD 10 | 11 | aws s3 cp --region=$REGION s3://$BUCKET/$1 - | gzip -dc | mysql -h $MYSQL_HOST -P $MYSQL_PORT --user=$MYSQL_USER --password=$MYSQL_PASSWORD $DB_NAME 12 | 13 | if [ "$?" != "0" ]; then 14 | echo "Restoring process fail" 15 | fi 16 | --------------------------------------------------------------------------------