Skip to content

Commit

Permalink
Merge branch 'release/0.3.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
Elias Oehen committed Feb 5, 2021
2 parents 12b1b00 + a5431cf commit 4b9a7f9
Show file tree
Hide file tree
Showing 13 changed files with 352 additions and 20 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

# Ignore example backup files
example/backup/
example/remote/
example/log/

# Ignore environment variable file
example/.env
25 changes: 25 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Contribution Guidelines

## GitHub Discussion

Join [GitHub discussions on the BBT Software docker-mssql-backup repository](https://github.com/bbtsoftware/docker-mssql-backup/discussions)
for questions and to discuss ideas & feature requests.

## Contribute

This repository uses [GitFlow] with default configuration.
Development is happening on `develop` branch.

To contribute:

* Fork this repository.
* Create a feature branch from `develop`.
* Implement your changes.
* Push your feature branch.
* Create a pull request.

> _We prefer the approach to create a pull-request per issue._
## Release

[GitFlow]: (http://nvie.com/posts/a-successful-git-branching-model/)
18 changes: 15 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,27 @@ ENV DB_SERVER="mssql" \
DB_NAMES="" \
CRON_SCHEDULE="0 1 * * sun" \
BACKUP_CLEANUP=false \
BACKUP_AGE=7
BACKUP_AGE=7 \
SKIP_BACKUP_LOG=false \
PACK="" \
ZIP_PASSWORD="" \
PUSH_REMOTE_MODE="" \
SMTP_HOST="" \
SMTP_PORT="" \
SMTP_AUTH="on" \
SMTP_USER="" \
SMTP_PASS="" \
SMTP_FROM="" \
SMTP_TLS="on" \
MAIL_TO=""

RUN apt-get update && \
apt-get install -y cron && \
apt-get install -y cron zip msmtp msmtp-mta mailutils && \
rm -rf /var/cache/apk/*

COPY backup.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/backup.sh

COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
ENTRYPOINT ["docker-entrypoint.sh"]
ENTRYPOINT ["docker-entrypoint.sh"]
31 changes: 29 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ For using the cleanup feature attach the same `/backup` volume in the `bbtsoftwa
| latest | Latest master build | ![Size](https://shields.beevelop.com/docker/image/image-size/bbtsoftwareag/mssql-backup/latest.svg?style=flat-square) |
| 0.1.0 | Release [0.1.0](https://github.com/bbtsoftware/docker-mssql-backup/releases/tag/0.1.0) | ![Size](https://shields.beevelop.com/docker/image/image-size/bbtsoftwareag/mssql-backup/0.1.0.svg?style=flat-square) |
| 0.2.0 | Release [0.2.0](https://github.com/bbtsoftware/docker-mssql-backup/releases/tag/0.2.0) | ![Size](https://shields.beevelop.com/docker/image/image-size/bbtsoftwareag/mssql-backup/0.2.0.svg?style=flat-square) |
| 0.3.0 | Release [0.2.0](https://github.com/bbtsoftware/docker-mssql-backup/releases/tag/0.3.0) | ![Size](https://shields.beevelop.com/docker/image/image-size/bbtsoftwareag/mssql-backup/0.3.0.svg?style=flat-square) |

### Configuration

Expand All @@ -44,8 +45,19 @@ These environment variables are supported:
| DB_NAMES | | Names of the databases for which a backup should be created. |
| TZ | | Timezone to use. |
| CRON_SCHEDULE | `0 1 * * sun` | Cron schedule for running backups. NOTE: There is no check if there's already a backup running when starting the backup job. Therefore time interval needs to be longer than the maximum expected backup time for all databases. |
| BACKUP_CLEANUP | `false` | Set to "true" if you want to let the cronjob remove files older than $BACKUP_AGE days |
| BACKUP_AGE | `7` | Number of days to keep backups in backup directory |
| BACKUP_CLEANUP | `false` | Set to "true" if you want to let the cronjob remove files older than $BACKUP_AGE days |
| BACKUP_AGE | `7` | Number of days to keep backups in backup directory |
| SKIP_BACKUP_LOG | `false` | Skip step to backup the transaction log . |
| PACK | | Possible values: `tar`, `zip`. If defined, compresses the output files into a single `.tar.gz` (or `zip`)-File. |
| ZIP_PASSWORD | | Sets the password for the zip to the given value. Only works if `PACK` is set to `zip` |
| PUSH_REMOTE_MODE | | The possible values `move` or `copy` activates pushing the backup files to a mapped remote directory. The volume `remote` must be mapped. |
| SMTP_HOST | | If this is set, email reporting is enabled by sending the results of the backup process to `MAIL_TO`. You pretty much have to define all the other `SMTP_*` variables, when the host is defined. |
| SMTP_PORT | | The port of the SMTP server |
| SMTP_USER | | The username used to login against the SMTP server |
| SMTP_PASS | | The password for connecting to the SMTP server |
| SMTP_FROM | | The E-mail address from which mails should be sent from |
| SMTP_TLS | `on` | Whether TLS should be used when connecting to the SMTP server |
| MAIL_TO | | The target E-mail address for receiving mail reports |

## Examples

Expand Down Expand Up @@ -86,4 +98,19 @@ services:
- default
```
### Example environment
We added a small docker environment in the [example](https://github.com/bbtsoftware/docker-mssql-backup/tree/develop/example)
subdirectory for `development` or `tests` with a own [readme](https://github.com/bbtsoftware/docker-mssql-backup/blob/develop/example/README.md) file.

## Discussion

For questions and to discuss ideas & feature requests, use the [GitHub discussions on the BBT Software docker-mssql-backup repository](https://github.com/bbtsoftware/docker-mssql-backup/discussions).

[![Join in the discussion on the BBT Software docker-mssql-backup repository](https://img.shields.io/badge/GitHub-Discussions-green?logo=github)](https://github.com/bbtsoftware/docker-mssql-backup/discussions)

## Contributing

Contributions are welcome. See [Contribution Guidelines](CONTRIBUTING.md).

[Microsoft SQL Server]: https://hub.docker.com/_/microsoft-mssql-server
97 changes: 83 additions & 14 deletions backup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,24 @@
echo "Backup started at $(date "+%Y-%m-%d %H:%M:%S")"

CURRENT_DATE=$(date +%Y%m%d%H%M)

# Intermediate working backup directory
WORKDIR="/backup/$CURRENT_DATE"

# Target backup directory
TARGETDIR="/backup"

# Remote backup directory
REMOTEDIR="/remote"

for CURRENT_DB in $DB_NAMES
do

# backup database files
BAK_FILENAME=/backup/$CURRENT_DATE.$CURRENT_DB.bak
BAK_FILENAME=$WORKDIR/$CURRENT_DATE.$CURRENT_DB.bak

echo "Backup database $CURRENT_DB to $BAK_FILENAME on $DB_SERVER..."
if /opt/mssql-tools/bin/sqlcmd -S "$DB_SERVER" -U "$DB_USER" -P "$DB_PASSWORD" -Q "BACKUP DATABASE [$CURRENT_DB] TO DISK = N'$BAK_FILENAME' WITH NOFORMAT, NOINIT, NAME = '$CURRENT_DB-full', SKIP, NOUNLOAD, STATS = 10"
if /opt/mssql-tools/bin/sqlcmd -S "$DB_SERVER" -U "$DB_USER" -P "$DB_PASSWORD" -b -Q "BACKUP DATABASE [$CURRENT_DB] TO DISK = N'$BAK_FILENAME' WITH NOFORMAT, NOINIT, NAME = '$CURRENT_DB-full', SKIP, NOUNLOAD, STATS = 10"
then
echo "Backup of database successfully created"
else
Expand All @@ -25,26 +35,85 @@ do
fi

# backup log files
TRN_FILENAME=/backup/$CURRENT_DATE.$CURRENT_DB.trn
if [ "$SKIP_BACKUP_LOG" = false ]; then
TRN_FILENAME=$WORKDIR/$CURRENT_DATE.$CURRENT_DB.trn

echo "Backup log of $CURRENT_DB to $TRN_FILENAME on $DB_SERVER..."
if /opt/mssql-tools/bin/sqlcmd -S "$DB_SERVER" -U "$DB_USER" -P "$DB_PASSWORD" -Q "BACKUP LOG [$CURRENT_DB] TO DISK = N'$TRN_FILENAME' WITH NOFORMAT, NOINIT, NAME = '$CURRENT_DB-log', SKIP, NOUNLOAD, STATS = 10"
then
echo "Backup of log successfully created"
echo "Backup log of $CURRENT_DB to $TRN_FILENAME on $DB_SERVER..."
if /opt/mssql-tools/bin/sqlcmd -S "$DB_SERVER" -U "$DB_USER" -P "$DB_PASSWORD" -b -Q "BACKUP LOG [$CURRENT_DB] TO DISK = N'$TRN_FILENAME' WITH NOFORMAT, NOINIT, NAME = '$CURRENT_DB-log', SKIP, NOUNLOAD, STATS = 10"
then
echo "Backup of log successfully created"
else
echo "Error creating log backup"
rm -rf "$TRN_FILENAME"
fi
else
echo "Error creating log backup"
rm -rf "$TRN_FILENAME"
echo "Backup of log skipped."
fi

# cleanup old backup files
if [ "$PACK" = "tar" ] || [ "$PACK" = "zip" ]; then
# compress backup files into tar.gz or zip file
echo ""
echo "Compress backup files"
FILES=$(find $WORKDIR -type f \( -name \*\.bak -o -name \*\.trn \))
if [ "$PACK" = "tar" ]; then
ARCHIVE_FILENAME="$WORKDIR/$CURRENT_DATE.$CURRENT_DB.tar.gz"
tar cfvz "$ARCHIVE_FILENAME" $FILES
retval=$?
elif [ "$PACK" = "zip" ]; then
ARCHIVE_FILENAME="$WORKDIR/$CURRENT_DATE.$CURRENT_DB.zip"
if [ "$ZIP_PASSWORD" ]; then
zip --password "$ZIP_PASSWORD" "$ARCHIVE_FILENAME" $FILES
retval=$?
else
zip "$ARCHIVE_FILENAME" $FILES
retval=$?
fi
fi

echo "Packing up results to $ARCHIVE_FILENAME"
if [ $retval -eq 0 ]; then
echo "Successfully packed backup into $ARCHIVE_FILENAME"
cp "$ARCHIVE_FILENAME" "$TARGETDIR"
else
echo "Failed creating $ARCHIVE_FILENAME"
fi

rm -rf $FILES
else
# Move files from intermediate work to target directory
echo "Copy backup files to target directory"
find $WORKDIR -type f -name "*.$CURRENT_DB.bak" -exec cp {} $TARGETDIR \;
find $WORKDIR -type f -name "*.$CURRENT_DB.trn" -exec cp {} $TARGETDIR \;
fi

# Push to remote directory
if [ "$PUSH_REMOTE_MODE" = "move" ] || [ "$PUSH_REMOTE_MODE" = "copy" ]; then
echo "Push backup to remote directory"
find $WORKDIR -type f -name "*.$CURRENT_DB.*" -exec cp {} $REMOTEDIR \;

if [ "$PUSH_REMOTE_MODE" = "move" ]; then
echo "Cleanup target directory"
find $TARGETDIR -type f -name "*.$CURRENT_DB.*" -exec rm {} \;
fi
fi

# Cleanup intermediate directory
echo "Cleanup intermediate directory"
find $WORKDIR -type f -name "*.$CURRENT_DB.*" -exec rm {} \;
rm -rf $WORKDIR

# Cleanup old backup files in target directory
if [ "$BACKUP_CLEANUP" = true ]; then
echo ""
echo "Backup cleanup is activated"
find /backup -type f -name "*.$CURRENT_DB.bak" -mtime +"$BACKUP_AGE" -exec echo {} " is deleted" \;
find /backup -type f -name "*.$CURRENT_DB.bak" -mtime +"$BACKUP_AGE" -exec rm {} \;
find $TARGETDIR -type f -name "*.$CURRENT_DB.*" -mtime +"$BACKUP_AGE" -exec echo {} " is deleted" \;
find $TARGETDIR -type f -name "*.$CURRENT_DB.*" -mtime +"$BACKUP_AGE" -exec rm {} \;

find /backup -type f -name "*.$CURRENT_DB.trn" -mtime +"$BACKUP_AGE" -exec echo {} " is deleted" \;
find /backup -type f -name "*.$CURRENT_DB.trn" -mtime +"$BACKUP_AGE" -exec rm {} \;
if [ "$PUSH_REMOTE_MODE" = "move" ] || [ "$PUSH_REMOTE_MODE" = "copy" ]; then
echo "Cleanup remote directory"
find $REMOTEDIR -type f -name "*.$CURRENT_DB.*" -mtime +"$BACKUP_AGE" -exec echo {} " is deleted" \;
find $REMOTEDIR -type f -name "*.$CURRENT_DB.*" -mtime +"$BACKUP_AGE" -exec rm {} \;
fi
else
echo "Backup files cleanup is disabled"
fi
Expand Down
71 changes: 70 additions & 1 deletion docker-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,63 @@
#!/bin/bash

# Create mail config if defined
if [[ $SMTP_HOST ]]; then

if [[ $SMTP_TLS = "on" ]]; then

# Configuration with TLS
cat << EOF > /etc/msmtprc
defaults
host $SMTP_HOST
port $SMTP_PORT
tls $SMTP_TLS
tls_starttls $SMTP_TLS
tls_trust_file /etc/ssl/certs/ca-certificates.crt
tls_certcheck $SMTP_TLS
account $SMTP_USER
auth $SMTP_AUTH
user $SMTP_USER
password "$SMTP_PASS"
from "$SMTP_USER"
account default: $SMTP_USER
aliases /etc/aliases
EOF

else

# Configuration without TLS
cat << EOF > /etc/msmtprc
defaults
host $SMTP_HOST
port $SMTP_PORT
account $SMTP_USER
auth $SMTP_AUTH
user $SMTP_USER
password "$SMTP_PASS"
from "$SMTP_USER"
account default: $SMTP_USER
aliases /etc/aliases
EOF

fi

cat << EOF > /etc/aliases
root: $SMTP_FROM
default: $SMTP_FROM
EOF

echo 'set sendmail="/usr/bin/msmtp -t"' > /etc/mail.rc

fi

# Store environment variables to pass to cron job
printenv | sed 's/^\([a-zA-Z0-9_]*\)=\(.*\)$/export \1="\2"/g' > /container_env.sh

Expand All @@ -9,7 +67,17 @@ cronSchedule=${cronSchedule%\"}
cronSchedule=${cronSchedule#\"}

# Create crontab definition
echo "$cronSchedule . /container_env.sh; /usr/local/bin/backup.sh >> /var/log/cron.log 2>&1" > /etc/cron.d/crontab.conf
if [[ $SMTP_HOST ]];
then
echo "Cron e-mail reporting activated. '${SMTP_HOST}'"
# (GH-39) Add (-a) paramter to append the log file, otherwise the log file is truncated every run.
# echo "$cronSchedule . /container_env.sh; /usr/local/bin/backup.sh 2>&1 | tee -a /var/log/cron.log | mail -s 'SQL Server Backup Result' $MAIL_TO 2>&1 | tee -a /var/log/cron.log" > /etc/cron.d/crontab.conf
echo "$cronSchedule . /container_env.sh; /usr/local/bin/backup.sh 2>&1 | tee /var/log/cron.log | mail -s 'SQL Server Backup Result' $MAIL_TO 2>&1 | tee /var/log/cron.log" > /etc/cron.d/crontab.conf
else
# (GH-39) Add (-a) paramter to append the log file, otherwise the log file is truncated every run.
# echo "$cronSchedule . /container_env.sh; /usr/local/bin/backup.sh 2>&1 | tee -a /var/log/cron.log" > /etc/cron.d/crontab.conf
echo "$cronSchedule . /container_env.sh; /usr/local/bin/backup.sh 2>&1 | tee /var/log/cron.log" > /etc/cron.d/crontab.conf
fi

# Apply cron job
crontab /etc/cron.d/crontab.conf
Expand All @@ -18,4 +86,5 @@ crontab /etc/cron.d/crontab.conf
touch /var/log/cron.log

echo "Starting cron task manager..."
echo " - Crontab = $cronSchedule"
cron && tail -f /var/log/cron.log
22 changes: 22 additions & 0 deletions example/.env.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
TZ=Europe/Zurich
DB_SERVER=db
DB_USER=SA
DB_PASSWORD=MySqlServerPassword1234
DB_NAMES=AdventureWorks2019
BACKUP_CLEANUP=true
BACKUP_AGE=1
CRON_SCHEDULE=*/1 * * * *
SKIP_BACKUP_LOG=false

PACK="zip"
ZIP_PASSWORD="ZipPassword1"
PUSH_REMOTE_MODE="move"

SMTP_HOST=
SMTP_PORT=
SMTP_AUTH=off
SMTP_TLS=on
SMTP_USER=
SMTP_PASS=
SMTP_FROM=
MAIL_TO=
20 changes: 20 additions & 0 deletions example/Dockerfile.mssql
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Adventure Works Database on SQL Server 2019
FROM mcr.microsoft.com/mssql/server

# Note: This isn't a secure password, and please don't use this for production.
ENV SA_PASSWORD=MySqlServerPassword1234
ENV ACCEPT_EULA=Y

ADD https://github.com/Microsoft/sql-server-samples/releases/download/adventureworks/AdventureWorksLT2019.bak /var/opt/mssql/backup/

USER root
RUN chown -R mssql /var/opt/mssql/backup
USER mssql

# Launch SQL Server, confirm startup is complete, restore the database, then terminate SQL Server.
RUN ( /opt/mssql/bin/sqlservr & ) | grep -q "Service Broker manager has started" \
&& sleep 5s \
&& /opt/mssql-tools/bin/sqlcmd -U sa -P ${SA_PASSWORD} -Q 'RESTORE DATABASE AdventureWorks2019 FROM DISK = "/var/opt/mssql/backup/AdventureWorksLT2019.bak" WITH MOVE "AdventureWorksLT2012_Data" to "/var/opt/mssql/data/AdventureWorks2019.mdf", MOVE "AdventureWorksLT2012_Log" to "/var/opt/mssql/data/AdventureWorks2019_log.ldf", NOUNLOAD, STATS = 5' \
&& /opt/mssql-tools/bin/sqlcmd -U sa -P ${SA_PASSWORD} -Q 'USE [AdventureWorks2019] ; ALTER DATABASE [AdventureWorks2019] SET RECOVERY FULL;' \
&& pkill sqlservr

Loading

0 comments on commit 4b9a7f9

Please sign in to comment.