mirror of
https://github.com/kossakovsky/n8n-install.git
synced 2026-03-07 14:23:08 +00:00
gost now always requires an external upstream proxy to function. wizard prompts for upstream proxy url when gost is selected. if no upstream provided, gost is removed from selection.
529 lines
15 KiB
Bash
Executable File
529 lines
15 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Generate data.json for the welcome page with active services and credentials
|
|
|
|
set -e
|
|
|
|
# Source the utilities file and initialize paths
|
|
source "$(dirname "$0")/utils.sh"
|
|
init_paths
|
|
|
|
OUTPUT_FILE="$PROJECT_ROOT/welcome/data.json"
|
|
|
|
# Load environment variables from .env file
|
|
load_env || exit 1
|
|
|
|
# Ensure welcome directory exists
|
|
mkdir -p "$PROJECT_ROOT/welcome"
|
|
|
|
# Remove existing data.json if it exists (always regenerate)
|
|
if [ -f "$OUTPUT_FILE" ]; then
|
|
rm -f "$OUTPUT_FILE"
|
|
fi
|
|
|
|
# Start building JSON
|
|
GENERATED_AT=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
|
|
# Build services array - each entry is a formatted JSON block
|
|
declare -a SERVICES_ARRAY
|
|
|
|
# n8n
|
|
if is_profile_active "n8n"; then
|
|
N8N_WORKER_COUNT_VAL="${N8N_WORKER_COUNT:-1}"
|
|
SERVICES_ARRAY+=(" \"n8n\": {
|
|
\"hostname\": \"$(json_escape "$N8N_HOSTNAME")\",
|
|
\"credentials\": {
|
|
\"note\": \"Create your account on first login\"
|
|
},
|
|
\"extra\": {
|
|
\"workers\": \"$N8N_WORKER_COUNT_VAL\"
|
|
}
|
|
}")
|
|
fi
|
|
|
|
# Flowise
|
|
if is_profile_active "flowise"; then
|
|
SERVICES_ARRAY+=(" \"flowise\": {
|
|
\"hostname\": \"$(json_escape "$FLOWISE_HOSTNAME")\",
|
|
\"credentials\": {
|
|
\"note\": \"Create your account on first login\"
|
|
}
|
|
}")
|
|
fi
|
|
|
|
# Open WebUI
|
|
if is_profile_active "open-webui"; then
|
|
SERVICES_ARRAY+=(" \"open-webui\": {
|
|
\"hostname\": \"$(json_escape "$WEBUI_HOSTNAME")\",
|
|
\"credentials\": {
|
|
\"note\": \"Create account on first login\"
|
|
}
|
|
}")
|
|
fi
|
|
|
|
# Grafana (monitoring)
|
|
if is_profile_active "monitoring"; then
|
|
SERVICES_ARRAY+=(" \"grafana\": {
|
|
\"hostname\": \"$(json_escape "$GRAFANA_HOSTNAME")\",
|
|
\"credentials\": {
|
|
\"username\": \"admin\",
|
|
\"password\": \"$(json_escape "$GRAFANA_ADMIN_PASSWORD")\"
|
|
}
|
|
}")
|
|
SERVICES_ARRAY+=(" \"prometheus\": {
|
|
\"hostname\": \"$(json_escape "$PROMETHEUS_HOSTNAME")\",
|
|
\"credentials\": {
|
|
\"username\": \"$(json_escape "$PROMETHEUS_USERNAME")\",
|
|
\"password\": \"$(json_escape "$PROMETHEUS_PASSWORD")\"
|
|
}
|
|
}")
|
|
fi
|
|
|
|
# Portainer
|
|
if is_profile_active "portainer"; then
|
|
SERVICES_ARRAY+=(" \"portainer\": {
|
|
\"hostname\": \"$(json_escape "$PORTAINER_HOSTNAME")\",
|
|
\"credentials\": {
|
|
\"note\": \"Create admin account on first login\"
|
|
}
|
|
}")
|
|
fi
|
|
|
|
# Postgresus
|
|
if is_profile_active "postgresus"; then
|
|
SERVICES_ARRAY+=(" \"postgresus\": {
|
|
\"hostname\": \"$(json_escape "$POSTGRESUS_HOSTNAME")\",
|
|
\"credentials\": {
|
|
\"note\": \"PostgreSQL credentials are shown in the PostgreSQL card\"
|
|
}
|
|
}")
|
|
fi
|
|
|
|
# Langfuse
|
|
if is_profile_active "langfuse"; then
|
|
SERVICES_ARRAY+=(" \"langfuse\": {
|
|
\"hostname\": \"$(json_escape "$LANGFUSE_HOSTNAME")\",
|
|
\"credentials\": {
|
|
\"username\": \"$(json_escape "$LANGFUSE_INIT_USER_EMAIL")\",
|
|
\"password\": \"$(json_escape "$LANGFUSE_INIT_USER_PASSWORD")\"
|
|
}
|
|
}")
|
|
fi
|
|
|
|
# Supabase
|
|
if is_profile_active "supabase"; then
|
|
SERVICES_ARRAY+=(" \"supabase\": {
|
|
\"hostname\": \"$(json_escape "$SUPABASE_HOSTNAME")\",
|
|
\"credentials\": {
|
|
\"username\": \"$(json_escape "$DASHBOARD_USERNAME")\",
|
|
\"password\": \"$(json_escape "$DASHBOARD_PASSWORD")\"
|
|
},
|
|
\"extra\": {
|
|
\"internal_api\": \"http://kong:8000\",
|
|
\"service_role_key\": \"$(json_escape "$SERVICE_ROLE_KEY")\"
|
|
}
|
|
}")
|
|
fi
|
|
|
|
# Dify
|
|
if is_profile_active "dify"; then
|
|
SERVICES_ARRAY+=(" \"dify\": {
|
|
\"hostname\": \"$(json_escape "$DIFY_HOSTNAME")\",
|
|
\"credentials\": {
|
|
\"note\": \"Create account on first login\"
|
|
},
|
|
\"extra\": {
|
|
\"api_endpoint\": \"https://$(json_escape "$DIFY_HOSTNAME")/v1\",
|
|
\"internal_api\": \"http://dify-api:5001\"
|
|
}
|
|
}")
|
|
fi
|
|
|
|
# Qdrant
|
|
if is_profile_active "qdrant"; then
|
|
SERVICES_ARRAY+=(" \"qdrant\": {
|
|
\"hostname\": \"$(json_escape "$QDRANT_HOSTNAME")\",
|
|
\"credentials\": {
|
|
\"api_key\": \"$(json_escape "$QDRANT_API_KEY")\"
|
|
},
|
|
\"extra\": {
|
|
\"dashboard\": \"https://$(json_escape "$QDRANT_HOSTNAME")/dashboard\",
|
|
\"internal_api\": \"http://qdrant:6333\"
|
|
}
|
|
}")
|
|
fi
|
|
|
|
# Weaviate
|
|
if is_profile_active "weaviate"; then
|
|
SERVICES_ARRAY+=(" \"weaviate\": {
|
|
\"hostname\": \"$(json_escape "$WEAVIATE_HOSTNAME")\",
|
|
\"credentials\": {
|
|
\"api_key\": \"$(json_escape "$WEAVIATE_API_KEY")\",
|
|
\"username\": \"$(json_escape "$WEAVIATE_USERNAME")\"
|
|
}
|
|
}")
|
|
fi
|
|
|
|
# Neo4j
|
|
if is_profile_active "neo4j"; then
|
|
SERVICES_ARRAY+=(" \"neo4j\": {
|
|
\"hostname\": \"$(json_escape "$NEO4J_HOSTNAME")\",
|
|
\"credentials\": {
|
|
\"username\": \"$(json_escape "$NEO4J_AUTH_USERNAME")\",
|
|
\"password\": \"$(json_escape "$NEO4J_AUTH_PASSWORD")\"
|
|
},
|
|
\"extra\": {
|
|
\"bolt_port\": \"7687\"
|
|
}
|
|
}")
|
|
fi
|
|
|
|
# SearXNG
|
|
if is_profile_active "searxng"; then
|
|
SERVICES_ARRAY+=(" \"searxng\": {
|
|
\"hostname\": \"$(json_escape "$SEARXNG_HOSTNAME")\",
|
|
\"credentials\": {
|
|
\"username\": \"$(json_escape "$SEARXNG_USERNAME")\",
|
|
\"password\": \"$(json_escape "$SEARXNG_PASSWORD")\"
|
|
}
|
|
}")
|
|
fi
|
|
|
|
# RAGApp
|
|
if is_profile_active "ragapp"; then
|
|
SERVICES_ARRAY+=(" \"ragapp\": {
|
|
\"hostname\": \"$(json_escape "$RAGAPP_HOSTNAME")\",
|
|
\"credentials\": {
|
|
\"username\": \"$(json_escape "$RAGAPP_USERNAME")\",
|
|
\"password\": \"$(json_escape "$RAGAPP_PASSWORD")\"
|
|
},
|
|
\"extra\": {
|
|
\"admin\": \"https://$(json_escape "$RAGAPP_HOSTNAME")/admin\",
|
|
\"docs\": \"https://$(json_escape "$RAGAPP_HOSTNAME")/docs\",
|
|
\"internal_api\": \"http://ragapp:8000\"
|
|
}
|
|
}")
|
|
fi
|
|
|
|
# RAGFlow
|
|
if is_profile_active "ragflow"; then
|
|
SERVICES_ARRAY+=(" \"ragflow\": {
|
|
\"hostname\": \"$(json_escape "$RAGFLOW_HOSTNAME")\",
|
|
\"credentials\": {
|
|
\"note\": \"Create account on first login\"
|
|
},
|
|
\"extra\": {
|
|
\"internal_api\": \"http://ragflow:80\"
|
|
}
|
|
}")
|
|
fi
|
|
|
|
# LightRAG
|
|
if is_profile_active "lightrag"; then
|
|
SERVICES_ARRAY+=(" \"lightrag\": {
|
|
\"hostname\": \"$(json_escape "$LIGHTRAG_HOSTNAME")\",
|
|
\"credentials\": {
|
|
\"username\": \"$(json_escape "$LIGHTRAG_USERNAME")\",
|
|
\"password\": \"$(json_escape "$LIGHTRAG_PASSWORD")\",
|
|
\"api_key\": \"$(json_escape "$LIGHTRAG_API_KEY")\"
|
|
},
|
|
\"extra\": {
|
|
\"docs\": \"https://$(json_escape "$LIGHTRAG_HOSTNAME")/docs\",
|
|
\"internal_api\": \"http://lightrag:9621\"
|
|
}
|
|
}")
|
|
fi
|
|
|
|
# Letta
|
|
if is_profile_active "letta"; then
|
|
SERVICES_ARRAY+=(" \"letta\": {
|
|
\"hostname\": \"$(json_escape "$LETTA_HOSTNAME")\",
|
|
\"credentials\": {
|
|
\"api_key\": \"$(json_escape "$LETTA_SERVER_PASSWORD")\"
|
|
}
|
|
}")
|
|
fi
|
|
|
|
# ComfyUI
|
|
if is_profile_active "comfyui"; then
|
|
SERVICES_ARRAY+=(" \"comfyui\": {
|
|
\"hostname\": \"$(json_escape "$COMFYUI_HOSTNAME")\",
|
|
\"credentials\": {
|
|
\"username\": \"$(json_escape "$COMFYUI_USERNAME")\",
|
|
\"password\": \"$(json_escape "$COMFYUI_PASSWORD")\"
|
|
}
|
|
}")
|
|
fi
|
|
|
|
# LibreTranslate
|
|
if is_profile_active "libretranslate"; then
|
|
SERVICES_ARRAY+=(" \"libretranslate\": {
|
|
\"hostname\": \"$(json_escape "$LT_HOSTNAME")\",
|
|
\"credentials\": {
|
|
\"username\": \"$(json_escape "$LT_USERNAME")\",
|
|
\"password\": \"$(json_escape "$LT_PASSWORD")\"
|
|
},
|
|
\"extra\": {
|
|
\"internal_api\": \"http://libretranslate:5000\"
|
|
}
|
|
}")
|
|
fi
|
|
|
|
# Docling
|
|
if is_profile_active "docling"; then
|
|
SERVICES_ARRAY+=(" \"docling\": {
|
|
\"hostname\": \"$(json_escape "$DOCLING_HOSTNAME")\",
|
|
\"credentials\": {
|
|
\"username\": \"$(json_escape "$DOCLING_USERNAME")\",
|
|
\"password\": \"$(json_escape "$DOCLING_PASSWORD")\"
|
|
},
|
|
\"extra\": {
|
|
\"ui\": \"https://$(json_escape "$DOCLING_HOSTNAME")/ui\",
|
|
\"docs\": \"https://$(json_escape "$DOCLING_HOSTNAME")/docs\",
|
|
\"internal_api\": \"http://docling:5001\"
|
|
}
|
|
}")
|
|
fi
|
|
|
|
# PaddleOCR
|
|
if is_profile_active "paddleocr"; then
|
|
SERVICES_ARRAY+=(" \"paddleocr\": {
|
|
\"hostname\": \"$(json_escape "$PADDLEOCR_HOSTNAME")\",
|
|
\"credentials\": {
|
|
\"username\": \"$(json_escape "$PADDLEOCR_USERNAME")\",
|
|
\"password\": \"$(json_escape "$PADDLEOCR_PASSWORD")\"
|
|
},
|
|
\"extra\": {
|
|
\"internal_api\": \"http://paddleocr:8080\"
|
|
}
|
|
}")
|
|
fi
|
|
|
|
# Postiz
|
|
if is_profile_active "postiz"; then
|
|
SERVICES_ARRAY+=(" \"postiz\": {
|
|
\"hostname\": \"$(json_escape "$POSTIZ_HOSTNAME")\",
|
|
\"credentials\": {
|
|
\"note\": \"Create account on first login\"
|
|
},
|
|
\"extra\": {
|
|
\"internal_api\": \"http://postiz:5000\"
|
|
}
|
|
}")
|
|
fi
|
|
|
|
# WAHA
|
|
if is_profile_active "waha"; then
|
|
SERVICES_ARRAY+=(" \"waha\": {
|
|
\"hostname\": \"$(json_escape "$WAHA_HOSTNAME")\",
|
|
\"credentials\": {
|
|
\"username\": \"$(json_escape "$WAHA_DASHBOARD_USERNAME")\",
|
|
\"password\": \"$(json_escape "$WAHA_DASHBOARD_PASSWORD")\",
|
|
\"api_key\": \"$(json_escape "$WAHA_API_KEY_PLAIN")\"
|
|
},
|
|
\"extra\": {
|
|
\"dashboard\": \"https://$(json_escape "$WAHA_HOSTNAME")/dashboard\",
|
|
\"swagger_user\": \"$(json_escape "$WHATSAPP_SWAGGER_USERNAME")\",
|
|
\"swagger_pass\": \"$(json_escape "$WHATSAPP_SWAGGER_PASSWORD")\",
|
|
\"internal_api\": \"http://waha:3000\"
|
|
}
|
|
}")
|
|
fi
|
|
|
|
# Crawl4AI (internal only)
|
|
if is_profile_active "crawl4ai"; then
|
|
SERVICES_ARRAY+=(" \"crawl4ai\": {
|
|
\"hostname\": null,
|
|
\"credentials\": {
|
|
\"note\": \"Internal service only\"
|
|
},
|
|
\"extra\": {
|
|
\"internal_api\": \"http://crawl4ai:11235\"
|
|
}
|
|
}")
|
|
fi
|
|
|
|
# Gotenberg (internal only)
|
|
if is_profile_active "gotenberg"; then
|
|
SERVICES_ARRAY+=(" \"gotenberg\": {
|
|
\"hostname\": null,
|
|
\"credentials\": {
|
|
\"note\": \"Internal service only\"
|
|
},
|
|
\"extra\": {
|
|
\"internal_api\": \"http://gotenberg:3000\",
|
|
\"docs\": \"https://gotenberg.dev/docs\"
|
|
}
|
|
}")
|
|
fi
|
|
|
|
# Ollama (internal only)
|
|
if is_profile_active "cpu" || is_profile_active "gpu-nvidia" || is_profile_active "gpu-amd"; then
|
|
SERVICES_ARRAY+=(" \"ollama\": {
|
|
\"hostname\": null,
|
|
\"credentials\": {
|
|
\"note\": \"Internal service only\"
|
|
},
|
|
\"extra\": {
|
|
\"internal_api\": \"http://ollama:11434\"
|
|
}
|
|
}")
|
|
fi
|
|
|
|
# Redis/Valkey (internal only, shown if n8n or langfuse active)
|
|
if is_profile_active "n8n" || is_profile_active "langfuse"; then
|
|
SERVICES_ARRAY+=(" \"redis\": {
|
|
\"hostname\": null,
|
|
\"credentials\": {
|
|
\"password\": \"$(json_escape "$REDIS_AUTH")\"
|
|
},
|
|
\"extra\": {
|
|
\"internal_url\": \"${REDIS_HOST:-redis}:${REDIS_PORT:-6379}\"
|
|
}
|
|
}")
|
|
fi
|
|
|
|
# PostgreSQL (internal only, shown if n8n or langfuse active)
|
|
if is_profile_active "n8n" || is_profile_active "langfuse"; then
|
|
SERVICES_ARRAY+=(" \"postgres\": {
|
|
\"hostname\": null,
|
|
\"credentials\": {
|
|
\"username\": \"$(json_escape "${POSTGRES_USER:-postgres}")\",
|
|
\"password\": \"$(json_escape "$POSTGRES_PASSWORD")\"
|
|
},
|
|
\"extra\": {
|
|
\"internal_host\": \"postgres\",
|
|
\"internal_port\": \"${POSTGRES_PORT:-5432}\",
|
|
\"database\": \"$(json_escape "${POSTGRES_DB:-postgres}")\"
|
|
}
|
|
}")
|
|
fi
|
|
|
|
# Python Runner (internal only)
|
|
if is_profile_active "python-runner"; then
|
|
SERVICES_ARRAY+=(" \"python-runner\": {
|
|
\"hostname\": null,
|
|
\"credentials\": {
|
|
\"note\": \"Mount: ./python-runner → /app\\nEntry: /app/main.py\\nLogs: make logs s=python-runner\"
|
|
}
|
|
}")
|
|
fi
|
|
|
|
# Cloudflare Tunnel
|
|
if is_profile_active "cloudflare-tunnel"; then
|
|
SERVICES_ARRAY+=(" \"cloudflare-tunnel\": {
|
|
\"hostname\": null,
|
|
\"credentials\": {
|
|
\"note\": \"Zero-trust access via Cloudflare network\"
|
|
},
|
|
\"extra\": {
|
|
\"recommendation\": \"Close ports 80, 443, 7687 in your VPS firewall after confirming tunnel connectivity\"
|
|
}
|
|
}")
|
|
fi
|
|
|
|
# Gost Proxy (internal only)
|
|
if is_profile_active "gost"; then
|
|
SERVICES_ARRAY+=(" \"gost\": {
|
|
\"hostname\": null,
|
|
\"credentials\": {
|
|
\"username\": \"$(json_escape "$GOST_USERNAME")\",
|
|
\"password\": \"$(json_escape "$GOST_PASSWORD")\"
|
|
},
|
|
\"extra\": {
|
|
\"note\": \"Routes AI traffic through external proxy for geo-bypass\",
|
|
\"proxy_url\": \"$(json_escape "$GOST_PROXY_URL")\",
|
|
\"upstream_proxy\": \"$(json_escape "$GOST_UPSTREAM_PROXY")\",
|
|
\"internal_api\": \"http://gost:8080\"
|
|
}
|
|
}")
|
|
fi
|
|
|
|
# Join array with commas and newlines
|
|
SERVICES_JSON=""
|
|
for i in "${!SERVICES_ARRAY[@]}"; do
|
|
if [ $i -gt 0 ]; then
|
|
SERVICES_JSON+=",
|
|
"
|
|
fi
|
|
SERVICES_JSON+="${SERVICES_ARRAY[$i]}"
|
|
done
|
|
|
|
# Build quick_start array based on active profiles
|
|
declare -a QUICK_START_ARRAY
|
|
STEP_NUM=1
|
|
|
|
# Step 1: Log into primary service (n8n or Flowise)
|
|
if is_profile_active "n8n"; then
|
|
QUICK_START_ARRAY+=(" {
|
|
\"step\": $STEP_NUM,
|
|
\"title\": \"Log into n8n\",
|
|
\"description\": \"Create your account on first login\"
|
|
}")
|
|
((STEP_NUM++))
|
|
elif is_profile_active "flowise"; then
|
|
QUICK_START_ARRAY+=(" {
|
|
\"step\": $STEP_NUM,
|
|
\"title\": \"Log into Flowise\",
|
|
\"description\": \"Create your account on first login\"
|
|
}")
|
|
((STEP_NUM++))
|
|
fi
|
|
|
|
# Step 2: Create first workflow (if n8n active)
|
|
if is_profile_active "n8n"; then
|
|
QUICK_START_ARRAY+=(" {
|
|
\"step\": $STEP_NUM,
|
|
\"title\": \"Create your first workflow\",
|
|
\"description\": \"Start with Manual Trigger + HTTP Request nodes\"
|
|
}")
|
|
((STEP_NUM++))
|
|
fi
|
|
|
|
# Step 3: Configure database backups (if postgresus active)
|
|
if is_profile_active "postgresus"; then
|
|
QUICK_START_ARRAY+=(" {
|
|
\"step\": $STEP_NUM,
|
|
\"title\": \"Configure database backups\",
|
|
\"description\": \"Set up Postgresus for automated PostgreSQL backups\"
|
|
}")
|
|
((STEP_NUM++))
|
|
fi
|
|
|
|
# Step 4: Monitor system (if monitoring active)
|
|
if is_profile_active "monitoring"; then
|
|
QUICK_START_ARRAY+=(" {
|
|
\"step\": $STEP_NUM,
|
|
\"title\": \"Monitor your system\",
|
|
\"description\": \"Use Grafana to track performance metrics\"
|
|
}")
|
|
((STEP_NUM++))
|
|
fi
|
|
|
|
# Join quick_start array
|
|
QUICK_START_JSON=""
|
|
for i in "${!QUICK_START_ARRAY[@]}"; do
|
|
if [ $i -gt 0 ]; then
|
|
QUICK_START_JSON+=",
|
|
"
|
|
fi
|
|
QUICK_START_JSON+="${QUICK_START_ARRAY[$i]}"
|
|
done
|
|
|
|
# Write final JSON with proper formatting
|
|
cat > "$OUTPUT_FILE" << EOF
|
|
{
|
|
"domain": "$(json_escape "$USER_DOMAIN_NAME")",
|
|
"generated_at": "$GENERATED_AT",
|
|
"services": {
|
|
$SERVICES_JSON
|
|
},
|
|
"quick_start": [
|
|
$QUICK_START_JSON
|
|
]
|
|
}
|
|
EOF
|
|
|
|
log_success "Welcome page data generated at: $OUTPUT_FILE"
|
|
log_info "Access it at: https://${WELCOME_HOSTNAME:-welcome.${USER_DOMAIN_NAME}}"
|