#!/bin/bash set -euo pipefail ############################################################################# # Portainer Stack Creator # # Creates new Portainer stacks via REST API using local YAML files. # # Usage: # ./create-stack.sh # # Example: # ./create-stack.sh gitea.yml ############################################################################# SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ENV_FILE="$SCRIPT_DIR/.env" # Colors RED='\033[0;31m' GREEN='\033[0;32m' BLUE='\033[0;34m' NC='\033[0m' log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } # Load credentials if [ ! -f "$ENV_FILE" ]; then log_error ".env file not found" exit 1 fi source "$ENV_FILE" PORTAINER_URL="${PORTAINER_URL:-http://localhost:8001}" # Validate arguments if [ $# -ne 1 ]; then log_error "Usage: $0 " exit 1 fi YAML_FILE="$1" STACK_NAME=$(basename "$YAML_FILE" .yml) if [ ! -f "$YAML_FILE" ]; then log_error "File not found: $YAML_FILE" exit 1 fi log_info "Creating stack: $STACK_NAME" # Authenticate log_info "Authenticating with Portainer..." TOKEN=$(curl -s -X POST "$PORTAINER_URL/api/auth" \ -H "Content-Type: application/json" \ -d "{\"username\":\"$PORTAINER_USERNAME\",\"password\":\"$PORTAINER_PASSWORD\"}" \ | python3 -c "import sys, json; print(json.load(sys.stdin)['jwt'])" 2>/dev/null) if [ -z "$TOKEN" ]; then log_error "Authentication failed" exit 1 fi log_success "Authenticated" # Get endpoint ID ENDPOINT_ID=$(curl -s -X GET "$PORTAINER_URL/api/endpoints" \ -H "Authorization: Bearer $TOKEN" \ | python3 -c "import sys, json; print(json.load(sys.stdin)[0]['Id'])" 2>/dev/null) if [ -z "$ENDPOINT_ID" ]; then log_error "Failed to get endpoint ID" exit 1 fi log_info "Endpoint ID: $ENDPOINT_ID" # Read YAML content YAML_CONTENT=$(cat "$YAML_FILE") # Create stack log_info "Creating stack in Portainer..." RESPONSE=$(curl -s -X POST "$PORTAINER_URL/api/stacks/create/standalone/string?endpointId=$ENDPOINT_ID" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d @- </dev/null || true