Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MySQL restore script from S3 #139

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions mysql-restore-s3/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
FROM alpine:latest

ADD install.sh install.sh
RUN sh install.sh && rm install.sh

ENV MYSQL_HOST **None**
ENV MYSQL_PORT 3306
ENV MYSQL_USER **None**
ENV MYSQL_PASSWORD **None**
ENV S3_ACCESS_KEY_ID **None**
ENV S3_SECRET_ACCESS_KEY **None**
ENV S3_BUCKET **None**
ENV S3_REGION us-west-1
ENV S3_ENDPOINT **None**
ENV S3_S3V4 no
ENV S3_PREFIX 'backup'
ENV S3_FILENAME **None**

ADD restore.sh restore.sh

CMD ["sh", "restore.sh"]
38 changes: 38 additions & 0 deletions mysql-restore-s3/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# mysql-restore-s3

Restore a MySQL backup from S3 to MySQL

## Warning

This will potentially put your database in a very bad state or complete destroy your data, be very careful.

## Limitations

This is made to restore a backup made from mysql-backup-s3, if you backup came from somewhere else please check your format.

* Your s3 bucket must only contain backups which you wish to restore - it will always grabs the 'latest' based on unix sort with no filtering, unless exact name provided
* They must be gzip encoded text sql files
* If your bucket has more than a 1000 files the latest may not be restore, only one s3 ls command is made

## Usage

Docker:
```sh
$ docker run -e S3_ACCESS_KEY_ID=key -e S3_SECRET_ACCESS_KEY=secret -e S3_BUCKET=my-bucket -e S3_PREFIX=backup -e MYSQL_USER=user -e MYSQL_PASSWORD=password -e MYSQL_HOST=localhost schickling/mysql-restore-s3
```

## Environment variables

- `MYSQL_HOST` the mysql host *required*
- `MYSQL_PORT` the mysql port (default: 3306)
- `MYSQL_USER` the mysql user *required*
- `MYSQL_PASSWORD` the mysql password *required*
- `MYSQL_OPTS` options to use when calling MySQL command (to set, e.g. encoding)
- `S3_ACCESS_KEY_ID` your AWS access key *required*
- `S3_SECRET_ACCESS_KEY` your AWS secret key *required*
- `S3_BUCKET` your AWS S3 bucket path *required*
- `S3_PREFIX` path prefix in your bucket (default: 'backup')
- `S3_FILENAME` filename from S3 used for backup. If not set, it will use the latest snapshot file.
- `S3_REGION` the AWS S3 bucket region (default: us-west-1)
- `S3_ENDPOINT` the AWS Endpoint URL, for S3 Compliant APIs such as [minio](https://minio.io) (default: none)
- `S3_S3V4` set to `yes` to enable AWS Signature Version 4, required for [minio](https://minio.io) servers (default: no)
16 changes: 16 additions & 0 deletions mysql-restore-s3/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/sh

# exit if a command fails
set -eo pipefail

apk update

# install mysqldump
apk add mysql-client

# install s3 tools
apk add python3 py3-pip
pip install awscli

# cleanup
rm -rf /var/cache/apk/*
62 changes: 62 additions & 0 deletions mysql-restore-s3/restore.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/bin/sh

set -eo pipefail

if [ "${S3_ACCESS_KEY_ID}" == "**None**" ]; then
echo "Warning: You did not set the S3_ACCESS_KEY_ID environment variable."
fi

if [ "${S3_SECRET_ACCESS_KEY}" == "**None**" ]; then
echo "Warning: You did not set the S3_SECRET_ACCESS_KEY environment variable."
fi

if [ "${S3_BUCKET}" == "**None**" ]; then
echo "You need to set the S3_BUCKET environment variable."
exit 1
fi

if [ "${MYSQL_HOST}" == "**None**" ]; then
echo "You need to set the MYSQL_HOST environment variable."
exit 1
fi

if [ "${MYSQL_USER}" == "**None**" ]; then
echo "You need to set the MYSQL_USER environment variable."
exit 1
fi

if [ "${MYSQL_PASSWORD}" == "**None**" ]; then
echo "You need to set the MYSQL_PASSWORD environment variable or link to a container named MYSQL."
exit 1
fi

if [ "${S3_IAMROLE}" != "true" ]; then
# env vars needed for aws tools - only if an IAM role is not used
export AWS_ACCESS_KEY_ID=$S3_ACCESS_KEY_ID
export AWS_SECRET_ACCESS_KEY=$S3_SECRET_ACCESS_KEY
export AWS_DEFAULT_REGION=$S3_REGION
fi

if [ "${S3_ENDPOINT}" == "**None**" ]; then
AWS_ARGS=""
else
AWS_ARGS="--endpoint-url ${S3_ENDPOINT}"
fi

if [ "${S3_FILENAME}" == "**None**" ]; then
echo "Finding latest backup"
S3_FILENAME=$(aws $AWS_ARGS s3 ls s3://$S3_BUCKET/$S3_PREFIX/ | sort | tail -n 1 | awk '{ print $4 }')
fi

MYSQL_HOST_OPTS="${MYSQL_OPTS} -h $MYSQL_HOST -P $MYSQL_PORT -u$MYSQL_USER -p$MYSQL_PASSWORD"

echo "Fetching ${S3_FILENAME} from S3"

aws $AWS_ARGS s3 cp s3://$S3_BUCKET/$S3_PREFIX/${S3_FILENAME} dump.sql.gz
gzip -d dump.sql.gz

echo "Restoring ${S3_FILENAME}"

mysql $MYSQL_HOST_OPTS < dump.sql

echo "MySQL Restore complete"