Skip to content

Migrate from ubuntu to alpine:3.6 #5

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

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
21 changes: 10 additions & 11 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
FROM ubuntu:xenial
FROM alpine:3.6
MAINTAINER Kevin Wittek <[email protected]>

RUN apk update
RUN apk add docker
RUN apk add py-pip
RUN apk add bash
RUN apk add gzip
RUN rm -rf /var/cache/apk/*
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should squash these layers into a single layer (so only one RUN statement). I know it wasn't done in the original version, but that's how it should be done ;)


RUN apt update && apt -y install apt-transport-https ca-certificates curl
RUN apt-key adv \
--keyserver hkp://ha.pool.sks-keyservers.net:80 \
--recv-keys 58118E89F3A912897C070ADBF76221572C52609D
RUN echo "deb https://apt.dockerproject.org/repo ubuntu-xenial main" | tee /etc/apt/sources.list.d/docker.list
RUN apt update && apt -y install docker-engine
RUN curl -L https://github.com/docker/compose/releases/download/1.9.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
RUN chmod +x /usr/local/bin/docker-compose
RUN pip install docker-compose

COPY docker_volume_backup.sh /

ENTRYPOINT ["/docker_volume_backup.sh", "/project/docker-compose.yml"]
COPY docker_full_backup.sh /
ENTRYPOINT ["/docker_volume_backup.sh", "/project/docker-compose.yml", "/docker_full_backup.sh"]
58 changes: 49 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,69 @@ Scripts for easy backup and restore of Docker volumes

## Usage

```
```bash
./docker_volume_backup.sh {compose_file_path} {project_name} {backup_path} {backup_or_restore} {restore_date}
# or
./docker_full_backup.sh {compose_file_path} {project_name} {backup_path} {backup_or_restore} {restore_date}
```

## Examples

### docker_volume_backup.sh

Backup

```
```bash
./docker_volume_backup.sh /home/kiview/Gitlab/docker-compose.yml gitlab $(pwd)/backup backup
```

Restore

```
```bash
./docker_volume_backup.sh /home/kiview/Gitlab/docker-compose.yml gitlab $(pwd)/backup restore 2016-10-19
```

### docker_full_backup.sh

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing introductory text which explains, that the following code should reside in its own bash script.

```bash
MODE=backup # or restore

path=/opt/mydocker/project1/docker-compose.yml
project=project1
BACKUP_DIR=/tmp/mybackups
DATE=xxxx-xx-xx

#export EXCLUDE_CONTAINER=1
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should not be commented in example.

#export EXCLUDE_VOLUMES=1

./docker_full_backup.sh $path $project $BACKUP_DIR $MODE $DATE
```

## Docker Container Usage
After building your container, you can use it like this:

After building your container,

```bash
docker build -t docker_volume_backup .
# or
./build.sh
```
docker run -v "/home/kiview/Gitlab/:/project" \
-v "$(pwd)/backup:/backup" \
-v /var/run/docker.sock:/var/run/docker.sock \
docker_volume_backup:latest Gitlab /backup backup

you can use it like this:

```bash
PROJECT_DIR # path to directory that contains the docker files, e.g. docker-compose.yml, Dockerfile, ...
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, this will only work if the example is in a bash file. The old examples could be run directly from the command line.

PROJECT_NAME # Name of the docker container, default is the directory name where docker-compose.yml is stored
BACKUP_DIR # directory where the tar-files are stored / readed
MODE # backup or restore
DATE # if MODE=restore than the date who should restore

# $MODE=backup --> $DATE is ignored
docker run \
-v "$PROJECT_DIR:/project" \
-v "$BACKUP_DIR:/backup" \
-v /var/run/docker.sock:/var/run/docker.sock \
docker_volume_backup:latest $PROJECT_NAME /backup $MODE $DATE
```
Note you don't need to provide the path to docker-compose.yml. It is assumed to be mounted under /project/docker-compose.yml.

Note you don't need to provide the path to docker-compose.yml. It is assumed to be mounted under /project/docker-compose.yml.
17 changes: 17 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash

# get location of script
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
SOURCE="$(readlink "$SOURCE")"
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"

#
if [ -z "$1" ] ; then
docker build -t docker_volume_backup "$DIR"
else
docker build -t docker_volume_backup "$1"
fi
121 changes: 121 additions & 0 deletions docker_full_backup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#!/bin/bash

alpine=alpine:3.6
cdir=containers
vdir=volumes
compose_file_path=$1
project_name=${2,,}
backup_path=$3
backup_or_restore=${4:-backup}
date_suffix=${5:-$(date -I)}

DO_CONTAINER=${EXCLUDE_CONTAINER:-0}
DO_VOLUMES=${EXCLUDE_VOLUMES:-0}

set -e

function backup_volume {
volume_name=$1
backup_destination=$2

docker run --rm -v $volume_name:/data -v $backup_destination:/backup $alpine tar -zcvf /backup/$vdir/$volume_name-$date_suffix.tar.gz /data
}

function backup_container {
container_id=$1
backup_destination=$2
fname="$backup_destination/$cdir/$container_id-$date_suffix.tar.gz"

docker export $container_id | gzip > $fname
}

function restore_volume {
volume_name=$1
backup_destination=$2
date=$date_suffix

docker run --rm -v $volume_name:/data $alpine find /data -mindepth 1 -delete
docker run --rm -v $volume_name:/data -v $backup_destination:/backup $alpine tar -xvf /backup/$vdir/$volume_name-$date.tar.gz -C .
}

function restore_container {
container_id=$1
backup_destination=$2
date=$date_suffix
fname="$backup_destination/$cdir/$container_id-$date_suffix.tar.gz"

["$(docker ps -a | grep $container_id)"] && docker rm -f $container_id
gunzip -c $fname | docker load
}


function main {
echo "Docker backup script for project: $project_name"
echo " mode: $backup_or_restore"

if [ "$backup_or_restore" == "backup" ] ; then
mkdir -p $backup_path/$cdir
mkdir -p $backup_path/$vdir
fi

echo " stopping running containers"
docker-compose -f $compose_file_path -p $project_name stop

if [ $DO_CONTAINER != 0 ] ; then
echo " container are excluded"
else
echo " enter container images"
#declare -a containers=()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove commented code.

#readarray -t containers < <(docker container ls --all -f name=$project_name | awk '{if (NR > 1) print $1}')
#for c in "${containers[@]}"
#do
#docker ps --all --quiet -f name=$project_name | while read -sr c ; do
docker-compose -f $compose_file_path -p $project_name ps -q | while read -sr c ; do
if [ "$backup_or_restore" == "backup" ]
then
echo " perform container backup: $c"
backup_container $c $backup_path
fi

if [ "$backup_or_restore" == "restore" ]
then
echo " restore container from backup: $c"
restore_container $c $backup_path
fi
done
fi

if [ $DO_VOLUMES != 0 ] ; then
echo " volumes are excluded"
else
echo " mounting volumes and performing backup/restore..."
#declare -a volumes=()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove commented code.

#readarray -t volumes < <(docker volume ls -f name=$project_name | awk '{if (NR > 1) print $2}')
#for v in "${volumes[@]}" ; do
docker-compose -f $compose_file_path -p $project_name config --volumes | while read -sr line ; do
# TODO: if it possible to get volumes ID's, put it in here!
v="${project_name}_$line"
if [ "$backup_or_restore" == "backup" ]
then
echo " perform volume backup: $v"
backup_volume $v $backup_path
fi

if [ "$backup_or_restore" == "restore" ]
then
echo " restore volume from backup: $v"
restore_volume $v $backup_path
fi
done
fi

echo " restarting containers"
docker-compose -f $compose_file_path -p $project_name start

# write date_id to file
echo "$date_suffix $project_name" >> "$backup_path/stored-backups.ids"

echo "finished"
}

main
16 changes: 10 additions & 6 deletions docker_volume_backup.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/bin/bash

alpine=alpine:3.6
compose_file_path=$1
project_name=${2,,}
backup_path=$3
Expand All @@ -13,26 +14,29 @@ function backup_volume {
backup_destination=$2
date_suffix=$(date -I)

docker run --rm -v $volume_name:/data -v $backup_destination:/backup ubuntu tar -zcvf /backup/$volume_name-$date_suffix.tar /data
docker run --rm -v $volume_name:/data -v $backup_destination:/backup $alpine tar -zcvf /backup/$volume_name-$date_suffix.tar /data
}

function restore_volume {
volume_name=$1
backup_destination=$2
date=$3

docker run --rm -v $volume_name:/data ubuntu find /data -mindepth 1 -delete
docker run --rm -v $volume_name:/data -v $backup_destination:/backup ubuntu tar -xvf /backup/$volume_name-$date.tar -C .
docker run --rm -v $volume_name:/data $alpine find /data -mindepth 1 -delete
docker run --rm -v $volume_name:/data -v $backup_destination:/backup $alpine tar -xvf /backup/$volume_name-$date.tar -C .
}

function main {
echo "Stopping running containers"
docker-compose -f $compose_file_path -p $project_name stop

echo "Mounting volumes and performing backup/restore..."
volumes=($(docker volume ls -f name=$project_name | awk '{if (NR > 1) print $2}'))
for v in "${volumes[@]}"
do
#declare -a volumes=()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove commented code.

#readarray -t volumes < <(docker volume ls -f name=$project_name | awk '{if (NR > 1) print $2}')
#for v in "${volumes[@]}" ; do
docker-compose -f $compose_file_path -p $project_name config --volumes | while read -sr line ; do
# TODO: if it possible to get volumes ID's, put it in here!
v="${project_name}_$line"
if [ "$backup_or_restore" == "backup" ]
then
echo "Perform backup"
Expand Down