back to scripts

update-all.sh

bash 77 lines secrets redacted

Pulls and recreates all Docker stacks to their latest images.

Note Live script from my home-lab server. Tokens, IDs, phone numbers and other secrets have been replaced with placeholders like <WHATSAPP_GROUP_ID> — everything else is the real, running code.
#!/bin/bash
set -o pipefail

BASE_DIR="$HOME/docker"
MEDIA_DIR="$BASE_DIR/media-stack"
JELLYFIN_CONFIG_DIR="$BASE_DIR/jellyfin/config"
JELLYFIN_BACKUP_DIR="$HOME/backups/jellyfin"
MEDIA_SERVICES=(gluetun qbittorrent prowlarr sonarr radarr flaresolverr jellyseerr)

backup_jellyfin_config() {
  if [ ! -d "$JELLYFIN_CONFIG_DIR" ]; then
    echo "ERROR: Jellyfin config directory missing: $JELLYFIN_CONFIG_DIR" >&2
    return 1
  fi

  mkdir -p "$JELLYFIN_BACKUP_DIR"
  backup="$JELLYFIN_BACKUP_DIR/jellyfin-config-pre-update-$(date +%Y%m%d-%H%M%S).tar.gz"
  echo ">>> Backing up Jellyfin config to: $backup"
  tar -C "$BASE_DIR/jellyfin" -czf "$backup" config
}

update_jellyfin() {
  echo "=== Safe Jellyfin Update Started ==="
  backup_jellyfin_config || return 1
  cd "$MEDIA_DIR" || return 1
  docker compose pull jellyfin
  docker compose up -d --no-deps jellyfin
  echo "=== Safe Jellyfin Update Finished ==="
}

case "${1:-}" in
  --jellyfin|jellyfin)
    update_jellyfin
    exit $?
    ;;
  --help|-h)
    echo "Usage: $0 [--jellyfin]"
    echo "  no args     Update all Docker Compose projects, excluding Jellyfin"
    echo "  --jellyfin  Backup Jellyfin config, then update only Jellyfin safely"
    exit 0
    ;;
esac

echo "=== Docker Compose Bulk Update Started ==="
echo "Base directory: $BASE_DIR"
echo

for dir in "$BASE_DIR"/*; do
  if [ -d "$dir" ]; then
    if [ -f "$dir/docker-compose.yml" ] || [ -f "$dir/compose.yml" ]; then
      project="$(basename "$dir")"
      if [[ "$project" == _* ]]; then
        echo ">>> Skipping disabled project: $project"
        echo
        continue
      fi

      echo ">>> Updating: $project"
      cd "$dir" || continue

      if [ "$project" = "media-stack" ]; then
        backup_jellyfin_config || exit 1
        echo ">>> Jellyfin is excluded from automatic bulk updates to preserve user data"
        docker compose pull "${MEDIA_SERVICES[@]}"
        docker compose up -d --no-deps "${MEDIA_SERVICES[@]}"
      else
        docker compose pull
        docker compose up -d
      fi

      echo ">>> Done: $project"
      echo
    fi
  fi
done

echo "=== All Docker Compose Projects Updated ==="

back to scripts