npx claudepluginhub yves-s/just-ship --plugin just-shipThis skill uses the workspace's default tool permissions.
Richte einen VPS als autonomes Entwicklungs-Environment ein. Der VPS empfaengt Tickets vom Board und entwickelt sie autonom.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Creates isolated Git worktrees for feature branches with prioritized directory selection, gitignore safety checks, auto project setup for Node/Python/Rust/Go, and baseline verification.
Richte einen VPS als autonomes Entwicklungs-Environment ein. Der VPS empfaengt Tickets vom Board und entwickelt sie autonom.
Gib NIEMALS API Keys, Tokens oder Passwoerter im Klartext im Chat aus. Wenn du Werte gesammelt hast, zeige sie maskiert:
ANTHROPIC_API_KEY=sk-ant-...d4f8 (erste 6 + letzte 4 Zeichen)GH_TOKEN=ghp_...x9mKapi_key=adp_...0d56Die echten Werte werden direkt per SSH auf den VPS geschrieben — sie muessen nie im Chat sichtbar sein.
IMMER zuerst ausfuehren bevor du den User nach Daten fragst.
Lies die pipeline.workspace_id aus project.json des aktuellen Projekts:
WS_ID=$(node -e "process.stdout.write(require('./project.json').pipeline?.workspace_id || '')")
Falls keine workspace_id vorhanden → direkt zu "Voraussetzungen" (Neuer VPS).
Via Supabase MCP (Pipeline-DB wsmnutkobalfrceavpxs):
SELECT id, name, vps_url, vps_api_key
FROM public.workspaces
WHERE id = '<workspace_id>';
Merke dir den name (Workspace-Name) fuer die Statusmeldung in 0.5a.
WICHTIG: Falls die Supabase-MCP-Abfrage fehlschlaegt (Auth-Fehler, MCP nicht verfuegbar), melde den Fehler dem User. Springe NIEMALS zu "Neuer VPS" nur weil die Abfrage fehlgeschlagen ist — der VPS existiert hoechstwahrscheinlich bereits.
Abfrage fehlgeschlagen?
→ Fehler melden: "Konnte Workspace-Daten nicht abfragen. Bitte Supabase MCP pruefen."
→ NICHT zu "Neuer VPS" springen
vps_url ist leer oder NULL?
→ JA: Neuer VPS → weiter mit "Voraussetzungen"
→ NEIN: VPS existiert bereits → 0.4 Health-Check
Extrahiere die IP/Domain aus vps_url und pruefe:
curl -sf "<vps_url>/health" --max-time 5
Health-Check erfolgreich ({"status":"ok"})?
→ JA: VPS laeuft → 0.5 Pruefen ob Projekt verbunden
→ NEIN: VPS nicht erreichbar → 0.6 Diagnose anbieten
Lies die server-config.json vom VPS und pruefe ob die project_id des aktuellen Projekts bereits eingetragen ist:
# IP/Domain aus vps_url extrahieren (ohne https:// und trailing slash)
VPS_HOST=$(echo "<vps_url>" | sed 's|https\?://||;s|/.*||')
# project_id aus lokalem project.json
LOCAL_PROJECT_ID=$(node -e "process.stdout.write(require('./project.json').pipeline?.project_id || '')")
# server-config.json vom VPS lesen und project_id suchen
PROJECT_MATCH=$(ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=accept-new root@$VPS_HOST "node -e \"
const cfg = JSON.parse(require('fs').readFileSync('/home/claude-dev/.just-ship/server-config.json','utf-8'));
const match = Object.entries(cfg.projects).find(([,p]) => p.project_id === '$LOCAL_PROJECT_ID');
process.stdout.write(match ? match[0] : '');
\"")
Projekt bereits auf VPS registriert (PROJECT_MATCH nicht leer)?
→ JA: Projekt ist verbunden → 0.5a Status melden mit Optionen
→ NEIN: Projekt fehlt → automatisch Phase 2 ausfuehren (KEIN User-Prompt)
WICHTIG: Wenn das aktuelle Projekt nicht auf dem VPS registriert ist, fuehre Phase 2 sofort und autonom aus. Keine Optionen anzeigen, keine Rueckfragen.
Nur wenn das aktuelle Projekt bereits auf dem VPS registriert ist.
Verwende den Workspace-Namen aus der DB-Abfrage (0.2) und parse den Health-Response fuer den Status:
VPS ist bereits eingerichtet und laeuft!
- Server: <vps_url>
- Workspace: <workspace_name> (aus DB-Abfrage 0.2)
- Projekt: <PROJECT_MATCH> (project_id: <LOCAL_PROJECT_ID>)
- Status: OK (<mode aus health-response>, <running aus health-response>)
Was moechtest du tun?
1. **Weiteres Projekt verbinden** — ein neues Repo auf dem VPS einrichten
2. **VPS updaten** — neues Image von GHCR pullen
3. **VPS-Status + Logs anzeigen** — Container-Status und aktuelle Logs
Warte auf die Antwort des Users und fuehre die gewaehlte Option aus:
ssh root@<VPS_HOST> "docker pull ghcr.io/yves-s/just-ship/pipeline:latest && cd /home/claude-dev/just-ship-ops && CLAUDE_UID=\$(id -u claude-dev) CLAUDE_GID=\$(id -g claude-dev) docker compose -f vps/docker-compose.yml up -d pipeline-server"
Dann Health-Check und Ergebnis melden.ssh root@<VPS_HOST> "docker ps --filter name=pipeline && docker logs --tail 30 \$(docker ps -q --filter name=pipeline) 2>&1"
VPS ist konfiguriert (<vps_url>), aber der Health-Check schlaegt fehl.
Moegliche Ursachen:
- Server ist gestoppt → Container neu starten
- Netzwerk/Firewall blockiert den Port
- Domain/DNS stimmt nicht mehr
Soll ich per SSH debuggen? Dafuer brauche ich die VPS IP-Adresse.
Falls der User die IP gibt, SSH-Verbindung testen und Container-Status pruefen:
ssh -o ConnectTimeout=5 root@<IP> "docker ps --filter name=pipeline && docker logs --tail 20 \$(docker ps -q --filter name=pipeline) 2>&1"
Nur wenn Phase 0 ergeben hat, dass kein VPS konfiguriert ist.
Teile dem User mit, was du brauchst. Gib klare Anweisungen, keine Fragen:
Ich richte jetzt just-ship auf deinem VPS ein. Dafuer brauche ich von dir:
1. **VPS IP-Adresse**
→ Hostinger Dashboard → dein VPS → IP kopieren
2. **SSH-Zugang**
→ Ich verbinde mich per SSH. Falls du noch keinen SSH Key hast:
ssh-keygen -t ed25519
Dann den Key auf den VPS kopieren:
ssh-copy-id root@DEINE-IP
Danach sollte `ssh root@DEINE-IP` ohne Passwort funktionieren.
3. **GitHub Personal Access Token**
→ https://github.com/settings/tokens/new
→ Scopes: repo, workflow, read:org → Generate → Token kopieren
→ WICHTIG: read:org wird benoetigt, damit gh auth funktioniert
4. **Anthropic API Key**
→ https://console.anthropic.com/settings/keys → Key kopieren
→ Wird fuer den Pipeline-Agent benoetigt (Claude Code CLI auf dem VPS)
5. **Subdomain fuer HTTPS** (empfohlen)
→ Setze einen DNS A-Record: just-ship.deinedomain.de → VPS-IP
→ Beim Domain-Provider unter DNS-Einstellungen einen A-Record anlegen
→ Paste die URL hier in den Chat, dann richte ich HTTPS gleich mit ein
→ Ohne HTTPS wird der API Key unverschluesselt uebertragen
Monitoring (Bugsink Error Tracking + Dozzle Live Logs) wird automatisch
mit eingerichtet — Credentials generiere ich fuer dich.
Gib mir diese 5 Dinge, dann mache ich den Rest.
Warte auf die Antwort des Users. Wenn alles da ist, weiter.
Alle Schritte laufen per SSH. Verwende ssh root@<IP> "<command>" fuer jeden Befehl.
ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=accept-new root@<IP> "echo 'SSH OK'"
Falls fehlschlaegt: Sage dem User was zu tun ist (ssh-copy-id nochmal, Firewall pruefen).
ssh root@<IP> "apt-get update && apt-get upgrade -y"
Docker:
ssh root@<IP> "curl -fsSL https://get.docker.com | sh"
Node.js 20 installieren (wird fuer project.json parsing und connect-project.sh benoetigt):
ssh root@<IP> "curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && apt-get install -y nodejs"
gh CLI auf dem Host installieren (wird fuer Repo-Cloning und claude-dev User gebraucht):
ssh root@<IP> "curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg 2>/dev/null && ARCH=\$(dpkg --print-architecture) && echo \"deb [arch=\${ARCH} signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main\" > /etc/apt/sources.list.d/github-cli.list && apt-get update -qq && apt-get install -y gh -qq"
Pruefen:
ssh root@<IP> "docker --version && docker compose version && node --version && gh --version"
ssh root@<IP> "id claude-dev 2>/dev/null || (useradd -m -u 1001 -s /bin/bash claude-dev && usermod -aG docker claude-dev)"
Git-Identity und GitHub-Auth fuer claude-dev einrichten:
ssh root@<IP> "su - claude-dev -c 'git config --global user.name \"Claude Dev\" && git config --global user.email \"claude-dev@pipeline\" && git config --global init.defaultBranch main'"
ssh root@<IP> "su - claude-dev -c 'echo <github-token> | gh auth login --with-token && gh auth setup-git'"
Falls gh auth login mit missing required scope 'read:org' fehlschlaegt:
Der User muss einen neuen Token mit read:org Scope erstellen. Sage dem User:
Der GitHub Token braucht den Scope `read:org`. Bitte erstelle einen neuen Token mit:
repo + workflow + read:org → https://github.com/settings/tokens/new
Alternativ als Fallback: GH_TOKEN als Env-Var setzen (umgeht die Scope-Validierung):
ssh root@<IP> "su - claude-dev -c 'echo \"export GH_TOKEN=<github-token>\" >> ~/.bashrc && GH_TOKEN=<github-token> gh auth setup-git 2>/dev/null || true'"
ssh root@<IP> "mkdir -p /home/claude-dev/projects /home/claude-dev/.just-ship && chown -R claude-dev:claude-dev /home/claude-dev"
Das Engine-Repo wird fuer setup.sh --update auf Projekt-Repos benoetigt.
Das Ops-Repo wird fuer docker-compose.yml, connect-project.sh und den Updater-Service benoetigt.
Der Pipeline-Server selbst kommt als fertiges Image von GHCR — kein Build auf dem VPS.
ssh root@<IP> "su - claude-dev -c 'git clone https://github.com/yves-s/just-ship.git /home/claude-dev/just-ship 2>/dev/null || (cd /home/claude-dev/just-ship && git pull)'"
ssh root@<IP> "su - claude-dev -c 'git clone https://github.com/yves-s/just-ship-ops.git /home/claude-dev/just-ship-ops 2>/dev/null || (cd /home/claude-dev/just-ship-ops && git pull)'"
Erstelle /home/claude-dev/.env mit API Keys und Monitoring-Credentials.
Diese gelten global fuer alle Projekte auf dem VPS.
Monitoring-Credentials generieren (lokal, vor dem SSH-Call):
BUGSINK_SECRET=$(openssl rand -hex 32)
MONITORING_PW=$(openssl rand -base64 16)
Fuer den Caddy-Basicauth-Hash muss caddy auf dem VPS verfuegbar sein (laeuft im Container).
Den Hash generieren wir spaeter in Phase 1.9 nach dem ersten docker compose up, und patchen die .env dann nach.
ssh root@<IP> "
CLAUDE_UID=\$(id -u claude-dev)
CLAUDE_GID=\$(id -g claude-dev)
cat > /home/claude-dev/.env << ENVEOF
GH_TOKEN=<github-token>
ANTHROPIC_API_KEY=<anthropic-key>
CLAUDE_UID=\$CLAUDE_UID
CLAUDE_GID=\$CLAUDE_GID
# Monitoring (Bugsink + Dozzle)
BUGSINK_SECRET_KEY=$BUGSINK_SECRET
BUGSINK_ADMIN_EMAIL=admin@<domain-oder-ip>
BUGSINK_ADMIN_PASSWORD=$MONITORING_PW
MONITORING_USER=admin
MONITORING_HASH=placeholder-wird-in-1.9-ersetzt
ENVEOF
chmod 600 /home/claude-dev/.env && chown claude-dev:claude-dev /home/claude-dev/.env"
Dem User die Monitoring-Credentials mitteilen (maskiert):
Monitoring-Zugang generiert:
- Bugsink Login: admin@<domain> / <MONITORING_PW erste 4>...
- Caddy Basicauth: admin / <MONITORING_PW erste 4>...
(gleiches Passwort fuer beide)
Generiere einen zufaelligen Pipeline Key:
PIPELINE_KEY=$(openssl rand -hex 32)
Erstelle /home/claude-dev/.just-ship/server-config.json:
ssh root@<IP> "cat > /home/claude-dev/.just-ship/server-config.json << CFGEOF
{
\"server\": {
\"port\": 3001,
\"pipeline_key\": \"$PIPELINE_KEY\"
},
\"workspace\": {
\"workspace_id\": \"\",
\"board_url\": \"\",
\"api_key\": \"\"
},
\"projects\": {}
}
CFGEOF
chown claude-dev:claude-dev /home/claude-dev/.just-ship/server-config.json
chmod 600 /home/claude-dev/.just-ship/server-config.json"
Die Workspace-Felder werden in Phase 2 befuellt.
Das Pipeline-Server-Image wird als fertiges Image von GHCR gepullt — kein Build auf dem VPS.
Ohne HTTPS (Default — startet pipeline-server, bugsink und dozzle, aber NICHT caddy):
ssh root@<IP> "docker pull ghcr.io/yves-s/just-ship/pipeline:latest && cd /home/claude-dev/just-ship-ops && CLAUDE_UID=\$(id -u claude-dev) CLAUDE_GID=\$(id -g claude-dev) docker compose -f vps/docker-compose.yml up -d pipeline-server bugsink dozzle"
Hinweis: Ohne HTTPS/Caddy sind Bugsink und Dozzle nur intern erreichbar (Docker-Netzwerk). Fuer direkten Zugriff temporaer Ports oeffnen: docker compose -f /home/claude-dev/just-ship-ops/vps/docker-compose.yml exec -d oder SSH-Tunnel: ssh -L 8000:localhost:8000 root@<IP>.
Mit HTTPS (falls User eine Domain angegeben hat): Zuerst Caddyfile erstellen, dann alle Services starten:
ssh root@<IP> "cat > /home/claude-dev/just-ship-ops/vps/Caddyfile << 'CADDYEOF'
<domain> {
reverse_proxy pipeline-server:3001
handle_path /errors/* {
basicauth {
{$MONITORING_USER:admin} {$MONITORING_HASH}
}
reverse_proxy bugsink:8000
}
handle_path /logs/* {
basicauth {
{$MONITORING_USER:admin} {$MONITORING_HASH}
}
reverse_proxy dozzle:8080
}
}
CADDYEOF
chown claude-dev:claude-dev /home/claude-dev/just-ship-ops/vps/Caddyfile"
ssh root@<IP> "docker pull ghcr.io/yves-s/just-ship/pipeline:latest && cd /home/claude-dev/just-ship-ops && CLAUDE_UID=\$(id -u claude-dev) CLAUDE_GID=\$(id -g claude-dev) docker compose -f vps/docker-compose.yml up -d"
Caddy-Basicauth-Hash generieren und .env patchen (nach dem ersten docker compose up, damit der Caddy-Container verfuegbar ist):
CADDY_HASH=$(ssh root@<IP> "docker compose -f /home/claude-dev/just-ship-ops/vps/docker-compose.yml exec -T caddy caddy hash-password --plaintext '$MONITORING_PW'" 2>/dev/null | tr -d '\r\n')
ssh root@<IP> "sed -i 's|MONITORING_HASH=placeholder-wird-in-1.9-ersetzt|MONITORING_HASH='\"$CADDY_HASH\"'|' /home/claude-dev/.env"
Falls der Caddy-Container noch nicht laeuft (kein HTTPS), den Hash lokal generieren oder mit htpasswd erzeugen:
# Alternative: htpasswd auf dem VPS installieren
ssh root@<IP> "apt-get install -y apache2-utils -qq && CADDY_HASH=\$(htpasswd -nbBC 10 '' '$MONITORING_PW' | tr -d ':\n' | sed 's/\$2y/\$2a/') && sed -i \"s|MONITORING_HASH=placeholder-wird-in-1.9-ersetzt|MONITORING_HASH=\$CADDY_HASH|\" /home/claude-dev/.env"
Nach dem Hash-Update die Container neu starten damit Caddy die Env-Var liest:
ssh root@<IP> "cd /home/claude-dev/just-ship-ops && docker compose -f vps/docker-compose.yml up -d"
Warte 10 Sekunden (Caddy braucht Zeit fuer HTTPS-Zertifikat), dann:
ssh root@<IP> "curl -s http://localhost:3001/health"
Erwartete Antwort: {"status":"ok","mode":"multi-project","running":null}
Falls HTTPS aktiv, auch extern pruefen:
curl -s "https://<domain>/health"
Falls Server restartet oder keine Antwort kommt, debuggen:
ssh root@<IP> "docker logs <container-name> 2>&1"
ssh root@<IP> "docker inspect <container-name> --format '{{.State.Status}} exit={{.State.ExitCode}}'"
Falls Container restartet ohne Logs — Entrypoint crasht. Mit ueberschriebenem Entrypoint testen:
ssh root@<IP> "docker run --rm --env-file /home/claude-dev/.env -e SERVER_CONFIG_PATH=/home/claude-dev/.just-ship/server-config.json -v /home/claude-dev/.just-ship:/home/claude-dev/.just-ship:ro --entrypoint sh ghcr.io/yves-s/just-ship/pipeline:latest -c 'cd /app && node --import tsx pipeline/server.ts 2>&1'"
Ohne HTTPS:
VPS ist eingerichtet!
- Server: http://<IP>:3001
- Pipeline Key: <PIPELINE_KEY> (maskiert)
- Monitoring: Bugsink + Dozzle laufen (nur intern erreichbar ohne HTTPS/Caddy)
- Status: Bereit fuer Projekte
HTTPS ist nicht aktiv. Fuer HTTPS siehe just-ship-ops/vps/README.md → "HTTPS einrichten".
Ohne HTTPS sind Bugsink (/errors/) und Dozzle (/logs/) nur per SSH-Tunnel erreichbar.
**Naechster Schritt: Projekt verbinden.**
Jetzt muss ich noch wissen, an welchem Projekt der VPS arbeiten soll.
Sag mir einfach den Namen oder Pfad — z.B. "mein-projekt" oder "~/Developer/mein-projekt".
Mit HTTPS:
VPS ist eingerichtet!
- Server: https://<domain>
- Pipeline Key: <PIPELINE_KEY> (maskiert)
- Monitoring:
- Error Tracking: https://<domain>/errors/ (Bugsink)
- Live Logs: https://<domain>/logs/ (Dozzle)
- Login: admin / <MONITORING_PW erste 4>...
- Status: Bereit fuer Projekte
**Naechster Schritt: Projekt verbinden.**
Jetzt muss ich noch wissen, an welchem Projekt der VPS arbeiten soll.
Sag mir einfach den Namen oder Pfad — z.B. "mein-projekt" oder "~/Developer/mein-projekt".
Wird pro Projekt ausgefuehrt. Verwende IMMER das Script aus dem Ops-Repo (just-ship-ops/vps/connect-project.sh) — KEINE manuellen Schritte.
Bestimme die nötigen Parameter:
VPS_HOST: IP oder Domain aus vps_url (aus Phase 0.2)PROJECT_PATH: Lokaler Pfad zum Projekt (User angeben lassen oder aus cwd)REPO: GitHub owner/repo (aus git remote -v im lokalen Projekt)SLUG: Projektname (aus project.json → name, oder Verzeichnisname)Optional (fuer Workspace-Config, falls noch nicht gesetzt):
BOARD_URL und BOARD_API_KEY: Aus write-config.sh read-workspaceWORKSPACE_ID: Aus project.json → pipeline.workspace_idVPS_HOST=$(echo "<vps_url>" | sed 's|https\?://||;s|/.*||')
# Ops-Repo Pfad (VPS-Infrastruktur lebt dort)
# Suche relativ zum Engine-Repo oder im gleichen Workspace
OPS_REPO=$(find "$(dirname "$(pwd)")" -maxdepth 2 -name "just-ship-ops" -type d 2>/dev/null | head -1)
if [ -z "$OPS_REPO" ]; then echo "ERROR: just-ship-ops repo nicht gefunden"; exit 1; fi
# Repo-URL aus git remote
REPO=$(cd <project-path> && git remote get-url origin | sed 's|.*github.com[:/]||;s|\.git$||')
# Slug aus project.json name
SLUG=$(node -e "process.stdout.write(require('<project-path>/project.json').name || '')")
# Board-Credentials (optional, fuer Workspace-Config)
WS_ID=$(node -e "process.stdout.write(require('<project-path>/project.json').pipeline?.workspace_id || '')")
WS_JSON=$(bash .claude/scripts/write-config.sh read-workspace --id "$WS_ID" 2>/dev/null || echo '{}')
BOARD_URL=$(echo "$WS_JSON" | node -e "try{process.stdout.write(JSON.parse(require('fs').readFileSync('/dev/stdin','utf-8')).board_url)}catch{}" 2>/dev/null)
BOARD_API_KEY=$(echo "$WS_JSON" | node -e "try{process.stdout.write(JSON.parse(require('fs').readFileSync('/dev/stdin','utf-8')).api_key)}catch{}" 2>/dev/null)
bash "$OPS_REPO/vps/connect-project.sh" \
--host "$VPS_HOST" \
--project-path "<project-path>" \
--repo "$REPO" \
--slug "$SLUG" \
--workspace-id "$WS_ID" \
--board-url "$BOARD_URL" \
--board-api-key "$BOARD_API_KEY"
Das Script macht deterministisch:
gh repo clone (oder updaten falls vorhanden)Jeder Schritt wird verifiziert. Bei Fehler: Abbruch mit klarer Meldung. Das Script gibt entweder "Projekt ist verbunden!" oder einen konkreten Fehler aus. Kein falscher Erfolg.
Falls vps_url und vps_api_key noch nicht in der DB stehen (neuer VPS), via Supabase MCP setzen:
UPDATE public.workspaces
SET vps_url = '<pipeline-url>', vps_api_key = '<PIPELINE_KEY>'
WHERE id = '<workspace_id>'
RETURNING id, name, vps_url;
Falls bereits gesetzt (bestehendes Setup): Diesen Schritt ueberspringen.
GH_TOKEN env var muss gesetzt sein (Phase 2.4)docker login ghcr.io falls Image privat--entrypoint sh debuggen (Phase 1.10)ufw allow 3001/tcp oder Hostinger Firewall-SettingsDer VPS laeuft mit zwei integrierten Monitoring-Diensten, die ueber Caddy erreichbar sind:
| URL | Dienst | Funktion |
|---|---|---|
https://<domain>/errors/ | Bugsink | Error Tracking UI (Sentry-kompatibel) |
https://<domain>/logs/ | Dozzle | Live Container Log Viewer |
Beide Endpunkte sind durch Caddy Basicauth geschuetzt.
Bugsink erstellt beim ersten Start automatisch einen Admin-User:
BUGSINK_ADMIN_EMAIL (Default: admin@localhost)BUGSINK_ADMIN_PASSWORD (Default: admin)Wichtig: Default-Credentials sofort aendern oder via Env-Vars ueberschreiben.
Folgende Variablen in /home/claude-dev/.env auf dem VPS setzen:
# Bugsink
BUGSINK_SECRET_KEY=<langer-zufaelliger-string>
BUGSINK_BASE_URL=https://<domain>/errors
BUGSINK_ADMIN_EMAIL=admin@example.com
BUGSINK_ADMIN_PASSWORD=<sicheres-passwort>
# Caddy Basicauth fuer /errors/ und /logs/
MONITORING_USER=admin
MONITORING_HASH=<caddy-hash>
Caddy erwartet einen bcrypt-Hash fuer Basicauth. Hash generieren mit:
caddy hash-password --plaintext 'dein-passwort'
Den ausgegebenen Hash als MONITORING_HASH in /home/claude-dev/.env eintragen.
Der pipeline-server Container hat BUGSINK_DSN=http://bugsink:8000/sentry/1/ gesetzt.
Das Sentry SDK verbindet sich automatisch — keine weitere Konfiguration noetig.