#!/bin/bash
# =========================================================================== #
# Description: Backup a docker-compose project, including all images, named and unnamed volumes, container filesystems, config, logs, and databases..
# Details: Backup a docker-compose project, including all images, named and unnamed volumes, container filesystems, config, logs, and databases..
# edit it so you can add environment variables for containers in the docker compose file so you can specify if you want to make backups of the attached volumes or not? For Example when backing-up Plex i dont want to backup the volume that contains my music and movies.
# Made for: Linux, docker-compose (Debian & Ubuntu).
# Requirements: doxker-compose | ssh-keygen | ssh-copy-id root@127.0.0.1 (replace IP)
# Make executable: chmod +x docker-compose-backup.sh
# Crontab @weekly: 0 0 * * MON /home/${staging_siteUser}/docker-compose-backup.sh 2>&1
# =========================================================================== #
#
# Variables: Source | Production
# set -o xtrace
set -o errexit
set -o errtrace
set -o nounset
set -o pipefail
IFS=$'\n'
now=$(date)
volume_exeption=("/media/Movies" "/run/udev")
echo "[START] $now"
# Fully backup a docker-compose project, including all images, named and unnamed volumes, container filesystems, config, logs, and databases.
project_dir="${1:-$PWD}"
if [ -f "$project_dir/docker-compose.yml" ]; then
echo "[i] Found docker-compose config at $project_dir/docker-compose.yml"
else
echo "[X] Could not find a docker-compose.yml file in $project_dir"
exit 1
fi
project_name=$(basename "$project_dir")
backup_time=$(date +"%Y-%m-%d_%H-%M")
backup_dir="$project_dir/backups/$backup_time"
# Source any needed environment variables
[ -f "$project_dir/docker-compose.env" ] && source "$project_dir/docker-compose.env"
[ -f "$project_dir/.env" ] && source "$project_dir/.env"
echo "[+] Backing up $project_name project to $backup_dir"
mkdir -p "$backup_dir"
echo " - Saving docker-compose.yml config"
cp "$project_dir/docker-compose.yml" "$backup_dir/docker-compose.yml"
# Optional: pause the containers before backing up to ensure consistency
#docker-compose pause
# Optional: run a command inside the contianer to dump your application's state/database to a stable file
echo " - Saving application state to ./dumps"
mkdir -p "$backup_dir/dumps"
# your database/stateful service export commands to run inside docker go here, e.g.
# docker compose exec postgres env PGPASSWORD="$POSTGRES_PASSWORD" pg_dump -U "$POSTGRES_USER" "$POSTGRES_DB" | gzip -9 > "$backup_dir/dumps/$POSTGRES_DB.sql.gz"
# docker compose exec redis redis-cli SAVE
# docker compose exec redis cat /data/dump.rdb | gzip -9 > "$backup_dir/dumps/redis.rdb.gz"
for service_name in $(docker-compose config --services); do
echo " - Pause service $service_name for backup"
docker-compose pause $service_name
container_id=$(docker-compose ps -q "$service_name")
service_dir="$backup_dir/$service_name"
echo "[*] Backing up ${project_name}__${service_name} to ./$service_name..."
mkdir -p "$service_dir"
# save config
echo " - Saving container config to ./$service_name/config.json"
docker inspect "$container_id" > "$service_dir/config.json"
# save logs
echo " - Saving stdout/stderr logs to ./$service_name/docker.{out,err}"
docker logs "$container_id" > "$service_dir/docker.out" 2> "$service_dir/docker.err"
# save data volumes
mkdir -p "$service_dir/volumes"
for source in $(docker inspect -f '{{range .Mounts}}{{println .Source}}{{end}}' "$container_id"); do
if [[ "${volume_exeption[@]}" =~ $source ]]
then
echo " - Volume $source found in exeption list, skipped !"
else
volume_dir="$service_dir/volumes$source"
echo " - Saving $source volume to ./$service_name/volumes$source"
mkdir -p $(dirname "$volume_dir")
cp -a -r "$source" "$volume_dir"
fi
done
echo " - UnPause service $service_name"
docker-compose unpause $service_name
done
echo "[*] Compressing backup folder to $backup_dir.tar.gz"
tar -zcf "$backup_dir.tar.gz" --totals "$backup_dir" && rm -Rf "$backup_dir"
echo "[√] Finished Backing up $project_name to $backup_dir.tar.gz."
curl "https://GOTIFY_URL/message?token=YOUR_TOKEN" -F "title=Backup $project_name" -F "message=Finished Backing up $project_name to $backup_dir.tar.gz." -F "priority=5"
# Resume the containers if paused above
#docker-compose unpause
1 Like
Thank you for the docker backup.
Its my next project.
1 Like