Script to stop and start Docker container for rclone backup

Hey guys. I found wolfv's excellent script for rclone here "wolfv Backup script". First of all, thank you so much for it. I love it! I wrote a little one myself to stop running docker containers so I could backup the appdate folder from my unraid server without interference.

It's my first bash script ever. So I'm sure there's plenty of room for improvement. But maybe it will serve as a suggestion for one or the other. Or maybe wolfv would like to implement such a feature in his script. I don't know how to send it to him, though, since the thread is already closed.

As I'm very inexperienced with bash scripts, I can't guarantee that it will work. So use it at your own risk :wink: However, it has worked for me for a while without any problems. There is also a hint where you can add your own exception handling.

Function: First, certain containers are stopped in a certain order. Then all the others that are currently running. Then wolf's script can be executed. Then the stopped containers are started again.

#!/bin/bash

log_path="./logfile.log"  # Path to the log file

# Function to write log messages
log() {
  echo "$(date +"%Y-%m-%d %H:%M:%S") - $1" >> "$log_path"
}

# Log file header
log "Script started."

# List of containers to stop first
docker_first=("Nextcloud" "MariaDB")

# Get the list of currently running containers
docker_result=$(docker container ls -q)

# List of containers to start last
docker_last=("MariaDB" "Nextcloud")

# Function to execute container stop/start commands
execute_containers() {
  local command="$1"         # Stop or start command
  shift
  local containers=("$@")   # Containers to stop/start

  local failed_containers=()  # Array to store containers that fail to stop/start

  for con in "${containers[@]}"; do
    log "Stopping $con ..."
    docker "$command" "$con"

    # Wait for container to stop/start within a timeout period
    local timeout=30
    local interval=5
    local elapsed=0

    while true; do
      container_status=$(docker inspect -f '{{.State.Status}}' "$con")

      if [[ "$command" == "start" ]]; then
        status="running"
      else
        status="exited"
      fi

      if [[ "$container_status" == "$status" ]]; then
        log "$con has successfully changed its status"
        break
      fi

      if (( elapsed >= timeout )); then
        log "Timeout: Container $con failed to $command"
        failed_containers+=("$con")
        break
      fi

      sleep "$interval"
      elapsed=$((elapsed + interval))
    done

    sleep 5
  done

  if [[ ${#failed_containers[@]} -gt 0 ]]; then
    log "Failed to $command the following containers: ${failed_containers[*]}"
    # Additional actions or error handling for containers that fail to stop/start
  fi
}

# Stop the containers listed in docker_first array
execute_containers "stop" "${docker_first[@]}"
log "Done stopping"

# Convert the docker_result string into an array
IFS=$'\n' read -rd '' -a containers <<< "$docker_result"

# Stop the remaining containers
execute_containers "stop" "${containers[@]}"
log "Done stopping remaining containers"

# Start the containers listed in docker_last array
execute_containers "start" "${docker_last[@]}"
log "Done starting"

# Start the remaining containers
execute_containers "start" "${containers[@]}"
log "Done starting remaining containers"

# Log file footer
log "Script completed."

1 Like

Sharing good stuff is always welcomed:)

but Instead of Help and Support post it in Howto guides category

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.