Browse Source

first commit

master
Luna 8 months ago
commit
ce665165ae

+ 12
- 0
.gitignore View File

@@ -0,0 +1,12 @@
1
+
2
+/project.geany
3
+
4
+*~
5
+\#*\#
6
+.\#*
7
+/logs
8
+
9
+/backups
10
+!/backups/.env.template
11
+
12
+/dev

+ 66
- 0
README.md View File

@@ -0,0 +1,66 @@
1
+
2
+# Luna's No-Footprint Incremental Backups
3
+
4
+<img src="https://badges.can-i.help/badge/Version-1.0-yellow.svg" />
5
+<img src="https://badges.can-i.help/badge/License-MIT-green.svg" />
6
+
7
+Multi-server incremental backup script with no remote footprint.
8
+
9
+<br>
10
+## Features
11
+
12
+- optional remote script execution before each backup
13
+- backup via rsync (very fast)
14
+- local incremental history via duplicity (go back in time in case of a hack)
15
+- very simple configuration
16
+- one script to backup all your servers
17
+
18
+<br>
19
+## Installation
20
+
21
+Requires git.
22
+
23
+```
24
+git clone ..
25
+```
26
+
27
+<br>
28
+## Per-server configuration
29
+
30
+If you don't have an SSH connection already configured for your server in ~/.ssh/config, do the following:
31
+```
32
+$EDITOR ~/.ssh/config
33
+```
34
+and add a block this way:
35
+```
36
+Host YOUR_SERVER_ID
37
+  Hostname THE_IP_OF_YOUR_SERVER
38
+  User root
39
+  Port 22
40
+  IdentityFile /home/YOUR_UNIX_USER/.ssh/YOUR_SERVER_IDENTITY_FILE
41
+```
42
+Save and test entering ```ssh YOUR_SERVER_ID```. If you login without entering credentials, you're done for this step.
43
+
44
+Then, to configure the server backup, do the following:
45
+
46
+```
47
+mkdir backups/YOUR_SERVER_ID
48
+cp backups/.env.template backups/YOUR_SERVER_ID/.env
49
+$EDITOR backups/YOUR_SERVER_ID/.env
50
+# replace at least the value of SSH_HOST and save.
51
+```
52
+
53
+<br>
54
+## Run backups
55
+
56
+```
57
+./backup-all.sh
58
+```
59
+
60
+To automate it, run ```crontab -e``` and add the same command (with an absolute path) following the cron synthaxis, and save. You're done.
61
+
62
+
63
+<br>
64
+## License
65
+
66
+MIT

+ 35
- 0
backup-all.sh View File

@@ -0,0 +1,35 @@
1
+#!/bin/bash
2
+
3
+SCRIPTPATH=$( cd "$(dirname "$0")" ; pwd -P )
4
+cd $SCRIPTPATH
5
+
6
+for d in $SCRIPTPATH/backups/*/; do
7
+    PROJECT=`basename "$d"`
8
+    if [ -f $SCRIPTPATH/backups/$PROJECT/.env ]; then
9
+	echo "===================================="
10
+	echo "backing up project $PROJECT"
11
+	echo "------------------------------------"
12
+        cd $SCRIPTPATH/backups/$PROJECT
13
+	source .env
14
+
15
+	if [ "$PREPARE_SCRIPT_ENABLED" == "1" ]; then
16
+	    ../../scripts/01-backup-prepare.sh
17
+	fi
18
+
19
+	if [ "$RSYNC_SCRIPT_ENABLED" == "1" ]; then
20
+	    ../../scripts/02-backup-rsync.sh
21
+	fi
22
+
23
+	if [ "$INCREMENTAL_SCRIPT_ENABLED" == "1" ]; then
24
+	    ../../scripts/03-backup-duplicity.sh
25
+	fi
26
+
27
+	echo "------------------------------------"
28
+	echo "backing up project $PROJECT complete"
29
+    	echo "===================================="
30
+	echo
31
+    fi
32
+done
33
+
34
+echo "all projects backend up successfuly"
35
+exit 0

+ 30
- 0
backups/.env.template View File

@@ -0,0 +1,30 @@
1
+
2
+
3
+# global server's ssh config
4
+# (make sure you have configured a matching ssh config into your ~/.ssh/config, pointing to a valid IdentityFile)
5
+
6
+SSH_USER=root
7
+SSH_HOST=<The "Host" label from your ~/.ssh/config file>
8
+
9
+
10
+# 01-backup-prepare script
11
+# (executes any backup-prepare.sh file inside folders of $REMOTE_FOLDER)
12
+
13
+PREPARE_SCRIPT_ENABLED=0
14
+REMOTE_FOLDER=/var/apps
15
+
16
+
17
+# 02-backup-rsync config (stored in )
18
+# (installs rsync if needed, and downloads a copy of $REMOTE_FOLDER into backups/last)
19
+
20
+RSYNC_SCRIPT_ENABLED=1
21
+
22
+
23
+# 03-backup-duplicity config
24
+# (keeps up-to-date an incremental history of backups/last into backups/incremental)
25
+
26
+INCREMENTAL_SCRIPT_ENABLED=0
27
+KEEP_FULL_BACKUPS=1
28
+KEEP_INCREMENTAL_BACKUPS=6W
29
+
30
+

+ 31
- 0
scripts/00-backup-prepare-remote-script.sh View File

@@ -0,0 +1,31 @@
1
+#!/bin/bash
2
+
3
+REMOTE_FOLDER="$1"
4
+cd $REMOTE_FOLDER
5
+
6
+echo "scanning folders in $REMOTE_FOLDER for backup-prepare.sh scripts.."
7
+echo
8
+
9
+for d in $REMOTE_FOLDER/*/ ; do
10
+    PROJECT=`basename "$d"`
11
+    if [ -f "$REMOTE_FOLDER/$PROJECT/backup-prepare.sh" ]; then
12
+	echo
13
+	echo "====================="
14
+	echo "$PROJECT ($REMOTE_FOLDER/$PROJECT)"
15
+	echo "---------------------"
16
+	echo
17
+	cd "$REMOTE_FOLDER/$PROJECT"
18
+	source .env 2> /dev/null && echo "root .env file loaded" || echo "no root .env file"
19
+	echo "executing backup-prepare.sh .."
20
+	source backup-prepare.sh
21
+	echo
22
+	echo "---------------------"
23
+    else
24
+	echo "no backup-prepare.sh file in $REMOTE_FOLDER/$PROJECT/, skipping"
25
+    fi
26
+done
27
+
28
+echo
29
+echo "============================"
30
+echo "all projects successfuly prepared for backup"
31
+exit 0

+ 12
- 0
scripts/01-backup-prepare.sh View File

@@ -0,0 +1,12 @@
1
+#!/bin/bash
2
+
3
+PROJECT=$(pwd -P)
4
+PROJECT=`basename "$PROJECT"`
5
+
6
+cd $( cd "$(dirname "$0")" ; pwd -P ) && cd .. && source backups/$PROJECT/.env
7
+
8
+
9
+ssh "$SSH_USER@$SSH_HOST" "bash -s" -- < scripts/00-backup-prepare-remote-script.sh "$REMOTE_FOLDER"
10
+exit 0
11
+
12
+

+ 19
- 0
scripts/02-backup-rsync.sh View File

@@ -0,0 +1,19 @@
1
+#!/bin/bash
2
+set -e
3
+
4
+PROJECT=$(pwd -P)
5
+PROJECT=`basename "$PROJECT"`
6
+
7
+cd $( cd "$(dirname "$0")" ; pwd -P ) && cd .. && source backups/$PROJECT/.env
8
+
9
+
10
+command -v rsync > /dev/null || apt-get install -y rsync
11
+
12
+rsync -av --delete \
13
+      --filter=':- .backupignore' \
14
+      --rsync-path="nice -n 19 ionice -c2 -n7 rsync" \
15
+      "$SSH_USER@$SSH_HOST:$REMOTE_FOLDER/" backups/$PROJECT/last
16
+
17
+exit 0
18
+
19
+

+ 16
- 0
scripts/03-backup-duplicity.sh View File

@@ -0,0 +1,16 @@
1
+#!/bin/bash
2
+set -e
3
+
4
+PROJECT=$(pwd -P)
5
+PROJECT=`basename "$PROJECT"`
6
+
7
+SCRIPTPATH=$( cd "$(dirname "$0")" ; pwd -P )/..
8
+cd $SCRIPTPATH
9
+source backups/$PROJECT/.env
10
+
11
+command -v duplicity || apt-get install -y duplicity
12
+
13
+duplicity --no-encryption -v5 --full-if-older-than $KEEP_INCREMENTAL_BACKUPS "$SCRIPTPATH/backups/$PROJECT/last" "file://$SCRIPTPATH/backups/$PROJECT/incremental" \
14
+    && duplicity --no-encryption remove-all-but-n-full $KEEP_FULL_BACKUPS --force "file://$SCRIPTPATH/backups/$PROJECT/incremental" 
15
+
16
+exit 0

Loading…
Cancel
Save