I want to create a before/after script to stop docker containers, was wondering if there is a duplicati environment variable that passes the backup job name that can be used in the script?
Script is meant to backup individual containers based on the container name. Make sure to name the backup job the same as your docker container.
#!/bin/bash
logfile=/config/docker_backup.log # /cofig is the location within duplicati docker _data directory
# Get duplicati job name which should be same as docker container name for script to work
dupdocker=${DUPLICATI__backup_name}
#dupdocker=ombi
# Get duplicati script event: BEFORE/AFTER
dupevent=${DUPLICATI__EVENTNAME}
#dupevent=BEFORE
# Get duplicati operation event: "Backup", "Cleanup", "Restore", or "DeleteAllButN"
dupopevent=${DUPLICATI__OPERATIONNAME}
if [ $dupopevent == "Backup" ]; then
printf "<<<=== ${dupopevent}\n" | tee -a $logfile
printf "Script start: $(date)\n" | tee -a $logfile
printf "Duplicati job name: ${dupdocker}\n" | tee -a $logfile
printf "Finding docker container: ${dupdocker}\n" | tee -a $logfile
runcont=$(docker ps -a -f name=${dupdocker} --format '{{.Names}}')
# Check if duplicati event if BEFORE script
if [ $dupevent == "BEFORE" ]; then
printf "Duplicati running BEFORE event script\n" | tee -a $logfile
# Check if docker container was found
if [ $dupdocker == $runcont ]; then
printf "Found container: ${runcont}\n" | tee -a $logfile
printf "Stopping container: ${runcont}\n" | tee -a $logfile
# Stop running docker container
$(docker stop $runcont > /dev/null 2>&1)
# Check state of docker container
docstate=$(docker inspect -f {{.State.Running}} $runcont)
printf "Container ${runcont} running state: ${docstate}\n" | tee -a $logfile
if [ $docstate == "false" ]; then
printf "Container ${runcont} stopped...\n" | tee -a $logfile
else
printf "Container ${runcont} still running, should be stopped!!!\n" | tee -a $logfile
fi
else
printf "No container found named: ${dupdocker}\n" | tee -a $logfile
fi
else
printf "Duplicati running AFTER event script\n" | tee -a $logfile
# Check if docker container was found
if [ $dupdocker == $runcont ]; then
printf "Found container: ${runcont}\n" | tee -a $logfile
printf "Starting container: ${runcont}\n" | tee -a $logfile
# Start stopped docker container
$(docker start $runcont > /dev/null 2>&1)
# Check state of docker container
docstate=$(docker inspect -f {{.State.Running}} $runcont)
printf "Container ${runcont} running state: ${docstate}\n" | tee -a $logfile
if [ "$docstate" == "true" ]; then
printf "Container ${runcont} started...\n" | tee -a $logfile
else
printf "Container ${runcont} still not running, should be started!!!\n" | tee -a $logfile
fi
else
printf "No container found named: ${dupdocker}\n" | tee -a $logfile
fi
fi
printf "Script stopped: $(date)\n" | tee -a $logfile
printf "===>>>\n" | tee -a $logfile
fi
Note: This is my first bash script, so use at own risk
#!/bin/bash
# Output to console, logfile, and docker log stdout. # fd/1 for stdout
# | tee /proc/1/fd/1 -a $logfile
logfile=/home/mirino/config/docker_backup.log # /config is the location within duplicati docker _data directory
# Get duplicati script event: BEFORE/AFTER
dupevent=${DUPLICATI__EVENTNAME}
# Get duplicati operation event: "Backup", "Cleanup", "Restore", or "DeleteAllButN"
dupopevent=${DUPLICATI__OPERATIONNAME}
if [ $dupopevent == "Backup" ]; then
event_name=" ${dupopevent} \"${DUPLICATI__backup_name}\""
separator_length=$(( ${#event_name} + 1 ))
separator=$(printf '=%.0s' $(seq 1 $separator_length))
printf "\n" | tee /proc/1/fd/1 -a $logfile
printf "$separator\n" | tee /proc/1/fd/1 -a $logfile
printf "$event_name\n" | tee /proc/1/fd/1 -a $logfile
printf "$separator\n" | tee /proc/1/fd/1 -a $logfile
printf "Script start: $(date)\n" | tee /proc/1/fd/1 -a $logfile
printf "Duplicati event: ${dupevent}\n" | tee /proc/1/fd/1 -a $logfile
if [ $dupevent == "BEFORE" ]; then
printf "Duplicati running BEFORE event script\n" | tee /proc/1/fd/1 -a $logfile
printf "Found $(docker ps -aq | wc -l) Docker containers\n" | tee /proc/1/fd/1 -a $logfile
containers=$(docker ps -aq)
total_containers=$(echo "$containers" | wc -w)
container_counter=0
printf ".....................................................\n" | tee /proc/1/fd/1 -a $logfile
if [ -n "$containers" ]; then
for container in $containers; do
container_counter=$((container_counter+1))
container_name=$(docker inspect --format '{{.Name}}' $container | sed 's/^\///')
printf "\n Stopping container ($container_counter/$total_containers): $container_name ($container)\n" | tee /proc/1/fd/1 -a $logfile
docker stop $container > /dev/null 2>&1
docstate=$(docker inspect -f {{.State.Running}} $container)
printf " Container running state: $docstate\n" | tee /proc/1/fd/1 -a $logfile
if [ "$docstate" == "false" ]; then
printf " Container stopped\n" | tee /proc/1/fd/1 -a $logfile
else
printf "Container $container_name ($container) still not running, should be started!!!\n" | tee /proc/1/fd/1 -a $logfile
fi
printf ".....................................................\n" | tee /proc/1/fd/1 -a $logfile
done
else
printf "No Docker containers found\n" | tee /proc/1/fd/1 -a $logfile
fi
else
printf "Duplicati running AFTER event script\n" | tee /proc/1/fd/1 -a $logfile
printf "Found $(docker ps -aq | wc -l) Docker containers\n" | tee /proc/1/fd/1 -a $logfile
printf ".....................................................\n" | tee /proc/1/fd/1 -a $logfile
containers=$(docker ps -aq)
total_containers=$(echo "$containers" | wc -w)
container_counter=0
if [ -n "$containers" ]; then
for container in $containers; do
container_counter=$((container_counter+1))
container_name=$(docker inspect --format '{{.Name}}' $container | sed 's/^\///')
printf " Starting container ($container_counter/$total_containers): $container_name ($container)\n" | tee /proc/1/fd/1 -a $logfile
docker start $container > /dev/null 2>&1
docstate=$(docker inspect -f {{.State.Running}} $container)
printf " Container running state: $docstate\n" | tee /proc/1/fd/1 -a $logfile
if [ "$docstate" == "true" ]; then
printf " Container started\n" | tee /proc/1/fd/1 -a $logfile
else
printf "Container $container_name ($container) still not running, should be started!!!\n" | tee /proc/1/fd/1 -a $logfile
fi
printf ".....................................................\n" | tee /proc/1/fd/1 -a $logfile
done
else
printf "No Docker containers found\n" | tee /proc/1/fd/1 -a $logfile
fi
fi
printf "Script stopped: $(date)\n" | tee /proc/1/fd/1 -a $logfile
printf "$separator\n" | tee /proc/1/fd/1 -a $logfile
fi
Output from log:
=========================
Backup "ALL CONTAINERS"
=========================
Script start: Wed 8 Nov 09:24:21 GMT 2023
Duplicati event: BEFORE
Duplicati running BEFORE event script
Found 2 Docker containers
.....................................................
Stopping container (1/2): mariadbtest (5bceeb32bff2)
Container running state: false
Container stopped
.....................................................
Stopping container (2/2): compassionate_curie (ed4875d4b374)
Container running state: false
Container stopped
.....................................................
Script stopped: Wed 8 Nov 09:24:26 GMT 2023
=========================
=========================
Backup "ALL CONTAINERS"
=========================
Script start: Wed 8 Nov 09:24:27 GMT 2023
Duplicati event: AFTER
Duplicati running AFTER event script
Found 2 Docker containers
.....................................................
Starting container (1/2): mariadbtest (5bceeb32bff2)
Container running state: true
Container started
.....................................................
Starting container (2/2): compassionate_curie (ed4875d4b374)
Container running state: true
Container started
.....................................................
Script stopped: Wed 8 Nov 09:24:31 GMT 2023
=========================
I have took the script - thank you so much.
Here is my variant of the script but with Notification to Telegram.
But if you have many containers, make sure you add ‘run-script-timeout’ to Advanced options (the same place where the options are set - run-script-before / run-script-after), because the default value is 60s and the backup may start before all containers are stopped.
#!/bin/bash
### GLOBAL VARIABLES ####
###https://duplicati.readthedocs.io/en/latest/appendix-g-example-scripts/#run-script-examplesh
# Duplicati variables
EVENTNAME=$DUPLICATI__EVENTNAME
OPERATIONNAME=$DUPLICATI__OPERATIONNAME
REMOTEURL=$DUPLICATI__REMOTEURL
# My variables
today=$(date +"%Y-%m-%d")
Telegram_TOKEN="YUOR_Telegram_TOKEN" # replace 'YUOR_Telegram_TOKEN' with your Telegram_TOKEN
Telegram_CHAT_ID="YUOR_Telegram_CHAT_ID" # replace 'YUOR_Telegram_CHAT_ID' with your Telegram_CHAT_ID
Telegram_SUCCESS="✅"
Telegram_ERROR="💥🔴"
logfile=/home/USERNAME/duplicatiLog/docker_backup.log # !!!!!!! replace 'USERNAME' with name of your system user or select a different location
# Get duplicati script event: BEFORE/AFTER
dupevent=${DUPLICATI__EVENTNAME}
# Get duplicati operation event: "Backup", "Cleanup", "Restore", or "DeleteAllButN"
dupopevent=${DUPLICATI__OPERATIONNAME}
# List to keep track of container states
started_containers_file="/home/USERNAME/duplicatiLog/started_containers.txt" # !!!!!!! replace 'USERNAME' with name of your system user or select a different location
if [ "$dupevent" == "BEFORE" ]; then
printf "Duplicati running BEFORE event script\n" | tee /proc/1/fd/1 -a "$logfile"
printf "Found $(docker ps -aq | wc -l) Docker containers\n" | tee /proc/1/fd/1 -a "$logfile"
containers=$(docker ps -q)
total_containers=$(echo "$containers" | wc -w)
container_counter=0
printf ".....................................................\n" | tee /proc/1/fd/1 -a "$logfile"
if [ -n "$containers" ]; then
> "$started_containers_file" # Clear the file
for container in $containers; do
container_counter=$((container_counter+1))
container_name=$(docker inspect --format '{{.Name}}' "$container" | sed 's/^\///')
printf "\n Stopping container ($container_counter/$total_containers): $container_name ($container)\n" | tee /proc/1/fd/1 -a "$logfile"
docker stop "$container" > /dev/null 2>&1
docstate=$(docker inspect -f {{.State.Running}} "$container")
printf " Container running state: $docstate\n" | tee /proc/1/fd/1 -a "$logfile"
if [ "$docstate" == "false" ]; then
printf " Container stopped\n" | tee /proc/1/fd/1 -a "$logfile"
echo "$container" >> "$started_containers_file" # Record the stopped containers
else
printf "Container $container_name ($container) still not running, should be started!!!\n" | tee /proc/1/fd/1 -a "$logfile"
fi
printf ".....................................................\n" | tee /proc/1/fd/1 -a "$logfile"
done
else
printf "No Docker containers found\n" | tee /proc/1/fd/1 -a "$logfile"
fi
# Check success and send to Telegram
if [ $? -eq 0 ]; then
# If successful, send a notification
DATE_TIME=$(date +'%Y-%m-%d %H:%M')
MESSAGE="$Telegram_SUCCESS $DATE_TIME"
else
# If unsuccessful, send a notification
DATE_TIME=$(date +'%Y-%m-%d %H:%M')
MESSAGE="$Telegram_ERROR $DATE_TIME"
fi
curl -s -X POST "https://api.telegram.org/bot$Telegram_TOKEN/sendMessage" -d "chat_id=$Telegram_CHAT_ID&text=Docker containers are stopped $MESSAGE"
elif [ "$dupevent" == "AFTER" ]; then
printf "Duplicati running AFTER event script\n" | tee /proc/1/fd/1 -a "$logfile"
printf "Found $(cat "$started_containers_file" | wc -l) Docker containers to start\n" | tee /proc/1/fd/1 -a "$logfile"
printf ".....................................................\n" | tee /proc/1/fd/1 -a "$logfile"
started_containers=$(cat "$started_containers_file")
total_containers=$(echo "$started_containers" | wc -w)
container_counter=0
if [ -n "$started_containers" ]; then
for container in $started_containers; do
container_counter=$((container_counter+1))
container_name=$(docker inspect --format '{{.Name}}' "$container" | sed 's/^\///')
printf " Starting container ($container_counter/$total_containers): $container_name ($container)\n" | tee /proc/1/fd/1 -a "$logfile"
docker start "$container" > /dev/null 2>&1
docstate=$(docker inspect -f {{.State.Running}} "$container")
printf " Container running state: $docstate\n" | tee /proc/1/fd/1 -a "$logfile"
if [ "$docstate" == "true" ]; then
printf " Container started\n" | tee /proc/1/fd/1 -a "$logfile"
else
printf "Container $container_name ($container) still not running, should be started!!!\n" | tee /proc/1/fd/1 -a "$logfile"
fi
printf ".....................................................\n" | tee /proc/1/fd/1 -a "$logfile"
done
else
printf "No Docker containers found to start\n" | tee /proc/1/fd/1 -a "$logfile"
fi
# Check success and send to Telegram
if [ $? -eq 0 ]; then
# If successful, send a notification
DATE_TIME=$(date +'%Y-%m-%d %H:%M')
MESSAGE="$Telegram_SUCCESS $DATE_TIME"
else
# If unsuccessful, send a notification
DATE_TIME=$(date +'%Y-%m-%d %H:%M')
MESSAGE="$Telegram_ERROR $DATE_TIME"
fi
curl -s -X POST "https://api.telegram.org/bot$Telegram_TOKEN/sendMessage" -d "chat_id=$Telegram_CHAT_ID&text=Docker containers are started $MESSAGE"
printf "Script stopped: $(date)\n" | tee /proc/1/fd/1 -a "$logfile"
printf "$separator\n" | tee /proc/1/fd/1 -a "$logfile"
fi