├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── Makefile ├── README.md ├── image ├── Dockerfile ├── environment │ └── default.yaml └── service │ └── backup │ ├── assets │ ├── README.md │ ├── cronjobs │ └── tool │ │ ├── backup │ │ └── restore │ └── startup.sh └── test ├── test.bats └── test_helper.bash /.gitignore: -------------------------------------------------------------------------------- 1 | /.twgit_features_subject 2 | /.twgit 3 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 0.2.1 4 | - Upgrade baseimage: light-baseimage:1.1.1 5 | 6 | ## 0.2.0 7 | - Upgrade baseimage: light-baseimage:1.1.0 (debian stretch) 8 | 9 | ## 0.1.2 10 | - Upgrade baseimage: light-baseimage:0.2.6 11 | 12 | ## 0.1.1 13 | - chmod 600 on backups 14 | 15 | ## 0.1.0 16 | - Initial release 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | NAME = osixia/backup 2 | VERSION = 0.2.1 3 | 4 | .PHONY: build build-nocache test tag-latest push push-latest release git-tag-version 5 | 6 | build: 7 | docker build -t $(NAME):$(VERSION) --rm image 8 | 9 | build-nocache: 10 | docker build -t $(NAME):$(VERSION) --no-cache --rm image 11 | 12 | test: 13 | env NAME=$(NAME) VERSION=$(VERSION) bats test/test.bats 14 | 15 | tag-latest: 16 | docker tag $(NAME):$(VERSION) $(NAME):latest 17 | 18 | push: 19 | docker push $(NAME):$(VERSION) 20 | 21 | push-latest: 22 | docker push $(NAME):latest 23 | 24 | release: build test tag-latest push push-latest 25 | 26 | git-tag-version: release 27 | git tag -a v$(VERSION) -m "v$(VERSION)" 28 | git push origin v$(VERSION) 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # osixia/backup 2 | 3 | [![Docker Pulls](https://img.shields.io/docker/pulls/osixia/backup.svg)][hub] 4 | [![Docker Stars](https://img.shields.io/docker/stars/osixia/backup.svg)][hub] 5 | [![](https://images.microbadger.com/badges/image/osixia/backup.svg)](http://microbadger.com/images/osixia/backup "Get your own image badge on microbadger.com") 6 | 7 | [hub]: https://hub.docker.com/r/osixia/backup/ 8 | 9 | Latest release: 0.2.1 - [Changelog](CHANGELOG.md) | [Docker Hub](https://hub.docker.com/r/osixia/backup/)  10 | 11 | **A docker image to periodically backup directories.** 12 | 13 | - [Quick start](#quick-start) 14 | - [Beginner Guide](#beginner-guide) 15 | - [Backup directory and data persistence](#backup-directory-and-data-persistence) 16 | - [Debug](#debug) 17 | - [Environment Variables](#environment-variables) 18 | - [Set your own environment variables](#set-your-own-environment-variables) 19 | - [Use command line argument](#use-command-line-argument) 20 | - [Link environment file](#link-environment-file) 21 | - [Make your own image or extend this image](#make-your-own-image-or-extend-this-image) 22 | - [Advanced User Guide](#advanced-user-guide) 23 | - [Extend osixia/backup:0.2.1 image](#extend-osixiabackup021-image) 24 | - [Make your own backup image](#make-your-own-backup-image) 25 | - [Tests](#tests) 26 | - [Under the hood: osixia/light-baseimage](#under-the-hood-osixialight-baseimage) 27 | - [Changelog](#changelog) 28 | 29 | ## Quick start 30 | 31 | # Run Backup Manager image 32 | docker run --volume /host/data:/data/input --volume /host/backup:/data/backup --detach osixia/backup:0.2.1 33 | 34 | ## Beginner Guide 35 | 36 | ### Backup directory and data persistence 37 | 38 | Backups are created by default in the directory `/data/backup` that has been declared as a volume, so your backup files are saved outside the container in a data volume. 39 | 40 | For more information about docker data volume, please refer to : 41 | 42 | > [https://docs.docker.com/userguide/dockervolumes/](https://docs.docker.com/userguide/dockervolumes/) 43 | 44 | ### Debug 45 | 46 | The container default log level is **info**. 47 | Available levels are: `none`, `error`, `warning`, `info`, `debug` and `trace`. 48 | 49 | Example command to run the container in `debug` mode: 50 | 51 | docker run --detach osixia/backup:0.2.1 --loglevel debug 52 | 53 | See all command line options: 54 | 55 | docker run osixia/backup:0.2.1 --help 56 | 57 | ## Environment Variables 58 | 59 | Environment variables defaults are set in **image/environment/default.yaml** 60 | 61 | See how to [set your own environment variables](#set-your-own-environment-variables) 62 | 63 | 64 | - **BACKUP_INPUT**: Directory to backup. Defaults to `/data/input`. 65 | 66 | 67 | - **BACKUP_OUTPUT**: Directorie to save backups in. Defaults to `/data/backup`. 68 | 69 | 70 | - **BACKUP_CRON_EXP**: Cron expression to schedule backup execution. Defaults to `0 4 * * *`. Every days at 4am. 71 | 72 | - **BACKUP_TTL**: Backup TTL in days. Defaults to `15`. 73 | 74 | ### Set your own environment variables 75 | 76 | #### Use command line argument 77 | Environment variables can be set by adding the --env argument in the command line, for example: 78 | 79 | docker run --env BACKUP_CRON_EXP="0 1 * * *" \ 80 | --detach osixia/backup:0.2.1 81 | 82 | #### Link environment file 83 | 84 | For example if your environment file is in : /data/backup/environment/my-env.yaml 85 | 86 | docker run --volume /data/backup/environment/my-env.yaml:/container/environment/01-custom/env.yaml \ 87 | --detach osixia/backup:0.2.1 88 | 89 | Take care to link your environment file to `/container/environment/XX-somedir` (with XX < 99 so they will be processed before default environment files) and not directly to `/container/environment` because this directory contains predefined baseimage environment files to fix container environment (INITRD, LANG, LANGUAGE and LC_CTYPE). 90 | 91 | #### Make your own image or extend this image 92 | 93 | This is the best solution if you have a private registry. Please refer to the [Advanced User Guide](#advanced-user-guide) just below. 94 | 95 | ## Advanced User Guide 96 | 97 | ### Extend osixia/backup:0.2.1 image 98 | 99 | If you need to add your custom TLS certificate, bootstrap config or environment files the easiest way is to extends this image. 100 | 101 | Dockerfile example: 102 | 103 | FROM osixia/backup:0.2.1 104 | MAINTAINER Your Name 105 | 106 | ADD environment /container/environment/01-custom 107 | 108 | 109 | ### Make your own backup image 110 | 111 | Clone this project : 112 | 113 | git clone https://github.com/osixia/docker-backup 114 | cd docker-backup 115 | 116 | Adapt Makefile, set your image NAME and VERSION, for example : 117 | 118 | NAME = osixia/backup 119 | VERSION = 0.2.0 120 | 121 | becomes : 122 | NAME = billy-the-king/backup 123 | VERSION = 0.2.0 124 | 125 | Add your custom keys, environment files, config ... 126 | 127 | Build your image : 128 | 129 | make build 130 | 131 | Run your image : 132 | 133 | docker run -d billy-the-king/backup:0.2.1 134 | 135 | ### Tests 136 | 137 | We use **Bats** (Bash Automated Testing System) to test this image: 138 | 139 | > [https://github.com/bats-core/bats-core](https://github.com/bats-core/bats-core) 140 | 141 | Install Bats, and in this project directory run : 142 | 143 | make test 144 | 145 | ### Under the hood: osixia/light-baseimage 146 | 147 | This image is based on osixia/light-baseimage. 148 | More info: https://github.com/osixia/docker-light-baseimage 149 | 150 | ## Changelog 151 | 152 | Please refer to: [CHANGELOG.md](CHANGELOG.md) 153 | -------------------------------------------------------------------------------- /image/Dockerfile: -------------------------------------------------------------------------------- 1 | # Use osixia/light-baseimage 2 | # sources: https://github.com/osixia/docker-light-baseimage 3 | FROM osixia/light-baseimage:1.1.1 4 | MAINTAINER Bertrand Gouny 5 | 6 | # Install Backup Manager, GNUPG for encryption and cron from baseimage 7 | # sources: https://github.com/osixia/docker-light-baseimage/blob/stable/image/tool/add-service-available 8 | #  https://github.com/osixia/docker-light-baseimage/blob/stable/image/service-available/:cron/download.sh 9 | RUN apt-get -y update \ 10 | && /container/tool/add-service-available :cron \ 11 | && apt-get clean \ 12 | && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 13 | 14 | # Add service directory to /container/service 15 | ADD service /container/service 16 | 17 | # Use baseimage install-service script 18 | # https://github.com/osixia/docker-light-baseimage/blob/stable/image/tool/install-service 19 | RUN /container/tool/install-service 20 | 21 | # Add default env variables 22 | ADD environment /container/environment/99-default 23 | 24 | # Set backup data in a data volume 25 | # Must match env var BM_REPOSITORY_ROOT in backup-manager.conf 26 | VOLUME ["/data/backup"] 27 | -------------------------------------------------------------------------------- /image/environment/default.yaml: -------------------------------------------------------------------------------- 1 | # Directories to backup: paths without spaces in their name 2 | BACKUP_INPUT: /data/input 3 | BACKUP_OUTPUT: /data/backup 4 | 5 | # Run backup at 4:00am 6 | BACKUP_CRON_EXP: 0 4 * * * 7 | 8 | # Delete backups that are over 15 days 9 | BACKUP_TTL: 15 10 | -------------------------------------------------------------------------------- /image/service/backup/assets/README.md: -------------------------------------------------------------------------------- 1 | Add your custom backup-manager.conf file here or mount one at docker run to /container/service/backup-manager/assets/backup-manager.conf 2 | -------------------------------------------------------------------------------- /image/service/backup/assets/cronjobs: -------------------------------------------------------------------------------- 1 | # Backup 2 | {{ BACKUP_CRON_EXP }} root /sbin/backup > /proc/1/fd/1 2>/proc/1/fd/2 3 | # empty line 4 | -------------------------------------------------------------------------------- /image/service/backup/assets/tool/backup: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | # Usage: /sbin/backup 4 | 5 | source /container/run/environment.sh 6 | 7 | # delete backups that are over $MMC_MAIL_BACKUP_TTL days 8 | find $BACKUP_OUTPUT -type f -mtime +$BACKUP_TTL -exec rm {} \; 9 | 10 | # Date format for the dump file name 11 | dateFileFormat="+%Y%m%dT%H%M%S" 12 | backupFilePath="$BACKUP_OUTPUT/$(date "$dateFileFormat").tar.gz" 13 | 14 | tar -czf $backupFilePath $BACKUP_INPUT 15 | chmod 600 $backupFilePath 16 | 17 | exit 0 18 | -------------------------------------------------------------------------------- /image/service/backup/assets/tool/restore: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | # Usage: /sbin/restore file 4 | file=$1 5 | 6 | source /container/run/environment.sh 7 | 8 | tar -xzf $BACKUP_OUTPUT/$file -C / 9 | 10 | exit 0 11 | -------------------------------------------------------------------------------- /image/service/backup/startup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | # set -x (bash debug) if log level is trace 4 | # https://github.com/osixia/docker-light-baseimage/blob/stable/image/tool/log-helper 5 | log-helper level eq trace && set -x 6 | 7 | # install image tools 8 | ln -sf ${CONTAINER_SERVICE_DIR}/backup/assets/tool/* /sbin/ 9 | 10 | # add cron jobs 11 | ln -sf ${CONTAINER_SERVICE_DIR}/backup/assets/cronjobs /etc/cron.d/backup 12 | chmod 600 ${CONTAINER_SERVICE_DIR}/backup/assets/cronjobs 13 | 14 | FIRST_START_DONE="${CONTAINER_STATE_DIR}/docker-backup-backup-first-start-done" 15 | # container first start 16 | if [ ! -e "$FIRST_START_DONE" ]; then 17 | 18 | # adapt cronjobs file 19 | sed -i "s|{{ BACKUP_CRON_EXP }}|${BACKUP_CRON_EXP}|g" ${CONTAINER_SERVICE_DIR}/backup/assets/cronjobs 20 | 21 | touch $FIRST_START_DONE 22 | fi 23 | 24 | exit 0 25 | -------------------------------------------------------------------------------- /test/test.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | load test_helper 3 | 4 | @test "image build" { 5 | 6 | run build_image 7 | [ "$status" -eq 0 ] 8 | 9 | } 10 | -------------------------------------------------------------------------------- /test/test_helper.bash: -------------------------------------------------------------------------------- 1 | setup() { 2 | IMAGE_NAME="$NAME:$VERSION" 3 | } 4 | 5 | # function relative to the current container / image 6 | build_image() { 7 | #disable outputs 8 | docker build -t $IMAGE_NAME $BATS_TEST_DIRNAME/../image &> /dev/null 9 | } 10 | 11 | run_image() { 12 | CONTAINER_ID=$(docker run $@ -d $IMAGE_NAME) 13 | CONTAINER_IP=$(get_container_ip_by_cid $CONTAINER_ID) 14 | } 15 | 16 | start_container() { 17 | start_containers_by_cid $CONTAINER_ID 18 | } 19 | 20 | stop_container() { 21 | stop_containers_by_cid $CONTAINER_ID 22 | } 23 | 24 | remove_container() { 25 | remove_containers_by_cid $CONTAINER_ID 26 | } 27 | 28 | clear_container() { 29 | stop_containers_by_cid $CONTAINER_ID 30 | remove_containers_by_cid $CONTAINER_ID 31 | } 32 | 33 | wait_process() { 34 | wait_process_by_cid $CONTAINER_ID $@ 35 | } 36 | 37 | # generic functions 38 | get_container_ip_by_cid() { 39 | local IP=$(docker inspect -f "{{ .NetworkSettings.IPAddress }}" $1) 40 | echo "$IP" 41 | } 42 | 43 | start_containers_by_cid() { 44 | for cid in "$@" 45 | do 46 | #disable outputs 47 | docker start $cid &> /dev/null 48 | done 49 | } 50 | 51 | stop_containers_by_cid() { 52 | for cid in "$@" 53 | do 54 | #disable outputs 55 | docker stop $cid &> /dev/null 56 | done 57 | } 58 | 59 | remove_containers_by_cid() { 60 | for cid in "$@" 61 | do 62 | #disable outputs 63 | docker rm $cid &> /dev/null 64 | done 65 | } 66 | 67 | clear_containers_by_cid() { 68 | stop_containers_by_cid $@ 69 | remove_containers_by_cid $@ 70 | } 71 | 72 | wait_process_by_cid() { 73 | cid=$1 74 | docker exec $cid /container/tool/wait-process ${@:2} 75 | } 76 | --------------------------------------------------------------------------------