Compare commits
8 Commits
649490f7f1
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
d1ecf93610
|
|||
|
6fe58e6126
|
|||
|
c6f35cb86b
|
|||
|
879de32228
|
|||
|
0924791310
|
|||
|
af5b9f90e6
|
|||
|
c8aeafe1a6
|
|||
|
c779861eed
|
21
README.md
21
README.md
@@ -13,6 +13,7 @@ A script to backup docker volumes and stack configuration on the servers.
|
|||||||
1. Copies the result to the `/backups` folder.
|
1. Copies the result to the `/backups` folder.
|
||||||
1. Cleans up / removes temporary directory that was created.
|
1. Cleans up / removes temporary directory that was created.
|
||||||
1. Restarts all the services.
|
1. Restarts all the services.
|
||||||
|
1. Removes backups older than 7 days.
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
@@ -21,7 +22,7 @@ stored in. This is done by editing the `/etc/fstab` file, and adding the
|
|||||||
following line.
|
following line.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
//<nas_ip>/docker/backups/<machine> /backups cifs credentials=/home/michael/smbcredentials,uid=0,gid=0 0 0
|
//<nas_ip>/docker/backups/<machine> /backups cifs credentials=/path/to/smbcredentials,uid=0,gid=0 0 0
|
||||||
```
|
```
|
||||||
|
|
||||||
Once that is done:
|
Once that is done:
|
||||||
@@ -66,11 +67,21 @@ sudo systemctl start backup.service
|
|||||||
|
|
||||||
## Restore
|
## Restore
|
||||||
|
|
||||||
This repository also contains a restore script that can restore the stacks and
|
The backup script also contains a restore command that can restore the stacks and
|
||||||
volumes from a backup (hopefully it's never needed!).
|
volumes from a backup (hopefully it's never needed!).
|
||||||
|
|
||||||
### Usage
|
### Usage
|
||||||
|
|
||||||
1. Download the script `wget https://git.housh.dev/homelab/backup/raw/branch/main/docker-restore.sh`
|
You can use the restore command without an argument to use the last backup as
|
||||||
1. Make script executable `chmod +x docker-restore.sh`
|
the archive to restore from.
|
||||||
1. Run the script `sudo ./docker-restore.sh /backups/<backup>.tar.gz`
|
|
||||||
|
```bash
|
||||||
|
sudo docker-backup restore
|
||||||
|
```
|
||||||
|
|
||||||
|
Or if you'd like to restore using a specific archive then you can pass in
|
||||||
|
argument that contains the path to the backup archive to use.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo docker-backup restore /backups/2025-04-21.tar.gz
|
||||||
|
```
|
||||||
|
|||||||
136
docker-backup.sh
136
docker-backup.sh
@@ -1,18 +1,44 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
function usage() {
|
||||||
|
cat <<EOF
|
||||||
|
docker-backup [options] [command] [args...]
|
||||||
|
|
||||||
|
COMMNADS:
|
||||||
|
|
||||||
|
run: Create a new backup (default if no options or command is passed)
|
||||||
|
restart: Restart all docker stacks.
|
||||||
|
restore: Restore from a backup, accepts argument which is path to an archive, if
|
||||||
|
no argument is supplied, then it will use the latest backup found.
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
|
||||||
|
-h | --help: Show this message.
|
||||||
|
--version: Show the version.
|
||||||
|
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==================================================
|
||||||
|
# Variables
|
||||||
|
# ==================================================
|
||||||
|
|
||||||
|
debug=${DEBUG:-}
|
||||||
|
version=1.0.1
|
||||||
today=$(date +'%F')
|
today=$(date +'%F')
|
||||||
stackdir="/etc/komodo/stacks"
|
stackdir="/etc/komodo/stacks"
|
||||||
backupdir="/backups"
|
backupdir="/backups"
|
||||||
|
services=($(find "$stackdir" -maxdepth 1 -mindepth 1 -type d))
|
||||||
services=()
|
|
||||||
readarray -d '' services < <(find "$stackdir" -maxdepth 1 -mindepth 1 -type d)
|
|
||||||
|
|
||||||
# Directories to backup.
|
# Directories to backup.
|
||||||
volumes=(
|
volumes=(
|
||||||
"/var/lib/docker/volumes"
|
"/var/lib/docker/volumes"
|
||||||
"/opt"
|
"/opt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# ==================================================
|
||||||
|
# Helpers
|
||||||
|
# ==================================================
|
||||||
|
|
||||||
function stopServices() {
|
function stopServices() {
|
||||||
echo "Stopping services..."
|
echo "Stopping services..."
|
||||||
for service in "${services[@]}"; do
|
for service in "${services[@]}"; do
|
||||||
@@ -27,8 +53,8 @@ function startServices() {
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
function copyStacks() {
|
function backupStacks() {
|
||||||
echo "Copying stack configuration..."
|
echo "Backing up stacks..."
|
||||||
local dir="$1/stacks"
|
local dir="$1/stacks"
|
||||||
mkdir "$dir"
|
mkdir "$dir"
|
||||||
for service in "${services[@]}"; do
|
for service in "${services[@]}"; do
|
||||||
@@ -36,14 +62,12 @@ function copyStacks() {
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
function copyVolumes() {
|
function backupVolumes() {
|
||||||
echo "Copying volumes..."
|
echo "Backing up volumes..."
|
||||||
local dir="$1/volumes"
|
local dir="$1/volumes"
|
||||||
mkdir "$dir"
|
mkdir "$dir"
|
||||||
for volume in "${volumes[@]}"; do
|
for volume in "${volumes[@]}"; do
|
||||||
# copy only directories.
|
cp -r --parents "$volume" "$dir"
|
||||||
find "$volume" -maxdepth 1 -mindepth 1 -type d -print0 |
|
|
||||||
xargs -0 -I {} cp -r --parents "$volume" "{}"
|
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,11 +82,39 @@ function backup() {
|
|||||||
function cleanBackups() {
|
function cleanBackups() {
|
||||||
echo "Removing old backups..."
|
echo "Removing old backups..."
|
||||||
# Remove backups older than 7 days.
|
# Remove backups older than 7 days.
|
||||||
find "$backupdir" -maxdepth 1 -mindepth 1 -name "*.tar.gz" -mtime +7 -print0 |
|
local dirs=($(find "$backupdir" -maxdepth 1 -mindepth 1 -name "*.tar.gz" -mtime +7))
|
||||||
xargs -0 -I {} rm -rf "{}"
|
for dir in "${dirs[@]}"; do
|
||||||
|
rm -rf "$dir"
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
function main() {
|
function copyIfNotDebug {
|
||||||
|
if [ -z "$debug" ]; then
|
||||||
|
cp -r "$1" "$2"
|
||||||
|
else
|
||||||
|
echo "$1 -> $2"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function restoreVolumes() {
|
||||||
|
echo "Copying volumes..."
|
||||||
|
local volumes=($(find "$1/volumes" -maxdepth 1 -mindepth 1 -type d))
|
||||||
|
for volume in "${volumes[@]}"; do
|
||||||
|
local dest="${volume#"$1"/volumes*}"
|
||||||
|
copyIfNotDebug "$volume" "$dest"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
function restoreStacks() {
|
||||||
|
echo "Copying stacks..."
|
||||||
|
local stacks=($(find "$1/stacks" -maxdepth 1 -mindepth 1 -type d))
|
||||||
|
for stack in "${stacks[@]}"; do
|
||||||
|
local dest="${stack#"$1"/stacks*}"
|
||||||
|
copyIfNotDebug "$stack" "$dest"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
function run() {
|
||||||
# stop services.
|
# stop services.
|
||||||
stopServices
|
stopServices
|
||||||
|
|
||||||
@@ -71,10 +123,10 @@ function main() {
|
|||||||
mkdir "$temp"
|
mkdir "$temp"
|
||||||
|
|
||||||
# copy stack configuration.
|
# copy stack configuration.
|
||||||
copyStacks "$temp"
|
backupStacks "$temp"
|
||||||
|
|
||||||
# copy stack configuration.
|
# copy stack configuration.
|
||||||
copyVolumes "$temp"
|
backupVolumes "$temp"
|
||||||
|
|
||||||
# Create a tar to backup.
|
# Create a tar to backup.
|
||||||
backup "$temp"
|
backup "$temp"
|
||||||
@@ -86,4 +138,56 @@ function main() {
|
|||||||
cleanBackups
|
cleanBackups
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function restore() {
|
||||||
|
# Parse the backup to use, if an argument is passed in use that as the source
|
||||||
|
# for the backup, otherwise use the last backup.
|
||||||
|
local archive="$1"
|
||||||
|
if [ -z "$archive" ]; then
|
||||||
|
echo "Backup not specified using latest backup..."
|
||||||
|
archive=$(find /backups -maxdepth 1 -mindepth 1 -name "*.tar.gz" | sort -nr | head -1)
|
||||||
|
fi
|
||||||
|
|
||||||
|
local dir="${archive%*.tar.gz}"
|
||||||
|
|
||||||
|
# unzip the archive.
|
||||||
|
echo "Unzipping backup: $archive"
|
||||||
|
tar -xvf "$archive"
|
||||||
|
|
||||||
|
# copy stacks and volumes to their locations.
|
||||||
|
restoreVolumes "$dir"
|
||||||
|
restoreStacks "$dir"
|
||||||
|
|
||||||
|
# cleanup
|
||||||
|
rm -rf "$dir"
|
||||||
|
|
||||||
|
echo "Restarting services..."
|
||||||
|
startServices
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==================================================
|
||||||
|
# MAIN
|
||||||
|
# ==================================================
|
||||||
|
|
||||||
|
function main() {
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
-h | --help)
|
||||||
|
usage && return 0
|
||||||
|
;;
|
||||||
|
--version)
|
||||||
|
echo "$version" && return 0
|
||||||
|
;;
|
||||||
|
restart)
|
||||||
|
startServices && return 0
|
||||||
|
;;
|
||||||
|
restore)
|
||||||
|
shift && restore "$@" && return 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
run "$@" && return 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
main "$@"
|
main "$@"
|
||||||
|
|||||||
@@ -1,46 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
debug=${DEBUG:-}
|
|
||||||
|
|
||||||
function copyIfNotDebug {
|
|
||||||
if [ -z "$debug" ]; then
|
|
||||||
cp -r "$1" "$2"
|
|
||||||
else
|
|
||||||
echo "$1 -> $2"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function copyVolumes() {
|
|
||||||
echo "Copying volumes..."
|
|
||||||
local volumes=($(find "$1/volumes" -maxdepth 1 -mindepth 1 -type d))
|
|
||||||
for volume in "${volumes[@]}"; do
|
|
||||||
local dest="${volume#"$1"/volumes*}"
|
|
||||||
copyIfNotDebug "$volume" "$dest"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
function copyStacks() {
|
|
||||||
echo "Copying stacks..."
|
|
||||||
local stacks=($(find "$1/stacks" -maxdepth 1 -mindepth 1 -type d))
|
|
||||||
for stack in "${stacks[@]}"; do
|
|
||||||
local dest="${stack#"$1"/stacks*}"
|
|
||||||
copyIfNotDebug "$stack" "$dest"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
function main() {
|
|
||||||
local archive="$1"
|
|
||||||
local dir="${archive%*.tar.gz}"
|
|
||||||
|
|
||||||
# unzip the archive.
|
|
||||||
tar -xvf "$archive"
|
|
||||||
|
|
||||||
# copy stacks and volumes to their locations.
|
|
||||||
copyVolumes "$dir"
|
|
||||||
copyStacks "$dir"
|
|
||||||
|
|
||||||
# cleanup
|
|
||||||
rm -rf "$dir"
|
|
||||||
}
|
|
||||||
|
|
||||||
main "$@"
|
|
||||||
23
install.sh
23
install.sh
@@ -4,6 +4,18 @@ baseurl="https://git.housh.dev/homelab/backup/raw/branch/main"
|
|||||||
systemdir="/etc/systemd/system"
|
systemdir="/etc/systemd/system"
|
||||||
bindir="/usr/local/bin"
|
bindir="/usr/local/bin"
|
||||||
|
|
||||||
|
function downloadScripts() {
|
||||||
|
local script="docker-backup"
|
||||||
|
# set the destination of the script.
|
||||||
|
local dest="$bindir/$script"
|
||||||
|
# Remove the file if it exists.
|
||||||
|
[ -f "$dest" ] && rm -f "$dest"
|
||||||
|
# download the script to the destination.
|
||||||
|
wget "$baseurl/$script.sh" -O "$dest"
|
||||||
|
# make the script executable.
|
||||||
|
chmod +x "$dest"
|
||||||
|
}
|
||||||
|
|
||||||
# Remove backup service file if it exists and install the service file.
|
# Remove backup service file if it exists and install the service file.
|
||||||
[ -f "$systemdir/backup.service" ] &&
|
[ -f "$systemdir/backup.service" ] &&
|
||||||
systemctl stop backup.timer &&
|
systemctl stop backup.timer &&
|
||||||
@@ -15,17 +27,10 @@ wget "$baseurl/backup.service" -O "$systemdir/backup.service"
|
|||||||
[ ! -f "$systemdir/backup.timer" ] &&
|
[ ! -f "$systemdir/backup.timer" ] &&
|
||||||
wget "$baseurl/backup.timer" -O "$systemdir/backup.timer"
|
wget "$baseurl/backup.timer" -O "$systemdir/backup.timer"
|
||||||
|
|
||||||
# Remove the backup script file if it exists and install the backup script.
|
downloadScripts
|
||||||
[ -f "$bindir/docker-backup" ] && rm -f "$bindir/docker-backup"
|
|
||||||
wget "$baseurl/docker-backup.sh" -O "$bindir/docker-backup" &&
|
|
||||||
chmod +x "$bindir/docker-backup"
|
|
||||||
|
|
||||||
# Remove the restore script file if it exists and install the restore script.
|
|
||||||
[ -f "$bindir/docker-restore" ] && rm -f "$bindir/docker-restore"
|
|
||||||
wget "$baseurl/docker-restore.sh" -O "$bindir/docker-restore" &&
|
|
||||||
chmod +x "$bindir/docker-restore"
|
|
||||||
|
|
||||||
# Start services
|
# Start services
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
systemctl start backup.timer
|
systemctl start backup.timer
|
||||||
systemctl start backup.service
|
systemctl start backup.service
|
||||||
|
systemctl status backup.service
|
||||||
|
|||||||
Reference in New Issue
Block a user