#!/bin/bash # # Portainer Stack Exporter # Connects to a Portainer instance via API and downloads all Stack compose files. # set -euo pipefail # Portainer configuration (Legacy Cluster) PORTAINER_URL="https://shipyard.snarfnet.net:9443" USERNAME="admin" PASSWORD="Cfxg0GqDfocWcteE" EXPORT_DIR="./portainer_stacks_export" if ! command -v jq &> /dev/null; then echo "ERROR: 'jq' is required to parse the JSON responses. Please install it." exit 1 fi mkdir -p "$EXPORT_DIR" echo "=== Portainer Stack Exporter ===" echo "Authenticating with Portainer at $PORTAINER_URL..." # 1. Authenticate and get JWT Token JWT=$(curl -s -k -X POST "${PORTAINER_URL}/api/auth" \ -H "Content-Type: application/json" \ -d "{\"Username\":\"${USERNAME}\",\"Password\":\"${PASSWORD}\"}" | jq -r '.jwt') if [ "$JWT" = "null" ] || [ -z "$JWT" ]; then echo "Authentication failed! Check your credentials or URL." exit 1 fi echo "Authentication successful." # 2. Fetch Stacks list echo "Fetching stacks..." STACKS_JSON=$(curl -s -k -H "Authorization: Bearer $JWT" "${PORTAINER_URL}/api/stacks") # 3. Iterate through stacks, grab the file, and save it echo "$STACKS_JSON" | jq -c '.[]' | while read -r stack; do STACK_ID=$(echo "$stack" | jq -r '.Id') STACK_NAME=$(echo "$stack" | jq -r '.Name') echo " -> Exporting stack: $STACK_NAME (ID: $STACK_ID)" FILE_CONTENT=$(curl -s -k -H "Authorization: Bearer $JWT" "${PORTAINER_URL}/api/stacks/${STACK_ID}/file" | jq -r '.StackFileContent') echo "$FILE_CONTENT" > "${EXPORT_DIR}/${STACK_NAME}.yml" done echo "=== Export Complete ===" echo "Your stack files have been saved to: ${EXPORT_DIR}/"