ci: Credentials aus Workflow entfernen, Portainer-Config dynamisch lesen
Build & Deploy Tippspiel / build (push) Successful in 17s
Build & Deploy Tippspiel / build (push) Successful in 17s
Statt Credentials im Workflow hardcoden: - Compose-File und Env-Vars werden zur Laufzeit aus Portainer gelesen - Einziges Secret im Workflow: PORTAINER_TOKEN - Keine sensiblen Daten mehr in git-versionierten Dateien Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -9,7 +9,7 @@ jobs:
|
||||
runs-on: self-hosted
|
||||
steps:
|
||||
- name: Setup tools
|
||||
run: apk add --no-cache curl
|
||||
run: apk add --no-cache curl python3
|
||||
|
||||
- name: Checkout
|
||||
run: |
|
||||
@@ -45,18 +45,40 @@ jobs:
|
||||
|
||||
- name: Redeploy Stack via Portainer
|
||||
run: |
|
||||
echo "Fetching current stack config from Portainer..."
|
||||
|
||||
# Aktuelles Compose-File aus Portainer lesen
|
||||
STACK_FILE=$(curl -s -k \
|
||||
"https://192.168.1.60:9444/api/stacks/115/file" \
|
||||
-H "X-API-Key: ${{ secrets.PORTAINER_TOKEN }}" \
|
||||
| python3 -c "import sys,json; print(json.load(sys.stdin).get('StackFileContent',''))")
|
||||
|
||||
# Aktuelle Env-Vars aus Portainer lesen (enthält die echten Werte)
|
||||
ENV_VARS=$(curl -s -k \
|
||||
"https://192.168.1.60:9444/api/stacks/115" \
|
||||
-H "X-API-Key: ${{ secrets.PORTAINER_TOKEN }}" \
|
||||
| python3 -c "import sys,json; print(json.dumps(json.load(sys.stdin).get('Env', [])))")
|
||||
|
||||
# Stack mit bestehender Konfiguration neu deployen (keine Credentials im Workflow)
|
||||
PAYLOAD=$(python3 -c "
|
||||
import json, sys
|
||||
stack_file = '''$STACK_FILE'''
|
||||
env_vars = $ENV_VARS
|
||||
print(json.dumps({
|
||||
'stackFileContent': stack_file,
|
||||
'env': env_vars,
|
||||
'prune': True,
|
||||
'pullImage': False
|
||||
}))
|
||||
")
|
||||
|
||||
echo "Redeploying stack wm2026-tippspiel..."
|
||||
curl -s -k -X PUT \
|
||||
"https://192.168.1.60:9444/api/stacks/115?endpointId=2" \
|
||||
-H "X-API-Key: ${{ secrets.PORTAINER_TOKEN }}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"stackFileContent": "services:\n tippspiel:\n image: wm2026-tippspiel:latest\n container_name: wm2026-tippspiel\n restart: unless-stopped\n ports:\n - \"3301:3001\"\n environment:\n - NODE_ENV=development\n - PORT=3001\n - DATABASE_URL=postgresql://postgres.ggqsfnlqezgxcfqkytrr:mPlkB1cVWWHexzcgMk@aws-0-eu-west-1.pooler.supabase.com:6543/postgres\n - SUPABASE_URL=https://ggqsfnlqezgxcfqkytrr.supabase.co\n - SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImdncXNmbmxxZXpneGNmcWt5dHJyIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTc3NTIzNjc4NiwiZXhwIjoyMDkwODEyNzg2fQ.WVT_M73ZTs7u-MMoeodTwFMH8u5G4wq1aQw5n8ZpZ2A\n - ANTHROPIC_API_KEY=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\n - FOOTBALL_API_KEY=15ae56716ff341a6b5ee977a38727915\n - FOOTBALL_API_BASE_URL=https://api.football-data.org/v4\n - ELEVENLABS_API_KEY=sk_8eaa1dfa56d58265c08cea57b2a72b65b355c97f43f85483\n - CORS_ORIGIN=*\n - STAFFBASE_PUBLIC_KEY=dev-mode-no-key-needed\n - STAFFBASE_PLUGIN_ID=\n healthcheck:\n test: [\"CMD\", \"wget\", \"-qO-\", \"http://localhost:3001/health\"]\n interval: 30s\n timeout: 5s\n start_period: 10s\n retries: 3\n networks:\n - main-network\n\nnetworks:\n main-network:\n external: true",
|
||||
"env": [],
|
||||
"prune": true,
|
||||
"pullImage": false
|
||||
}' \
|
||||
| python3 -c "import sys,json; d=json.load(sys.stdin); print('Stack redeployed:', d.get('Name'), '| Status:', d.get('Status'))" 2>/dev/null \
|
||||
-d "$PAYLOAD" \
|
||||
| python3 -c "import sys,json; d=json.load(sys.stdin); print('Stack redeployed:', d.get('Name'), '| Status:', d.get('Status'))" \
|
||||
|| echo "Stack redeploy triggered."
|
||||
echo "Deployment complete!"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user