9.1 KiB
Deployment Dokumentation: Lessons Learned
Projektübersicht
Deployment einer SvelteKit + PocketBase Anwendung auf Hetzner VPS mit Coolify.
Finale Architektur
┌─────────────────────────────────────────────┐
│ Hetzner VPS (91.99.221.179) │
│ │
│ ┌────────────────────────────────────────┐ │
│ │ Coolify Platform │ │
│ │ │ │
│ │ ┌───────────────────────────────────┐ │ │
│ │ │ Docker Container │ │ │
│ │ │ │ │ │
│ │ │ ┌──────────────────────────────┐ │ │ │
│ │ │ │ Supervisor Process Manager │ │ │ │
│ │ │ │ │ │ │ │
│ │ │ │ ├─ SvelteKit (Port 3000) │ │ │ │
│ │ │ │ └─ PocketBase (Port 8090) │ │ │ │
│ │ │ └──────────────────────────────┘ │ │ │
│ │ └───────────────────────────────────┘ │ │
│ └────────────────────────────────────────┘ │
└─────────────────────────────────────────────┘
Was wir gemacht haben
1. Repository Vorbereitung
Probleme die wir lösen mussten:
-
MCP Server Submodule: Git erkannte den MCP Server als Submodule, was Deployment verhinderte
- Lösung: MCP Server aus Git entfernt und in
.gitignorehinzugefügt
- Lösung: MCP Server aus Git entfernt und in
-
NPM Dependencies: Versionskonflikte bei
globalsundprettier-plugin-tailwindcss- Lösung: Versionen angepasst und
--legacy-peer-depsverwendet
- Lösung: Versionen angepasst und
-
Fehlende Dependencies:
@tailwindcss/vitewar nicht installiert- Lösung: Package nachinstalliert
2. Docker Setup
Dockerfile Evolution:
Version 1 (Fehlgeschlagen):
COPY backend/pb_data /app/pb_data # Fehler: Ordner existiert nicht im Git
Version 2 (Final):
# Multi-stage build für optimale Größe
FROM node:20-alpine AS builder
# Build mit legacy-peer-deps
RUN npm ci --legacy-peer-deps
FROM node:20-alpine
# Supervisor für Process Management
RUN apk add --no-cache supervisor wget unzip
# PocketBase Binary direkt herunterladen
RUN wget https://github.com/pocketbase/pocketbase/releases/download/v0.26.2/pocketbase_0.26.2_linux_amd64.zip
3. Process Management mit Supervisor
supervisord.conf Herausforderungen:
Problem: Environment Variables Expansion
# Fehlgeschlagen:
environment=ORIGIN="%(ENV_ORIGIN)s" # ENV_ORIGIN nicht definiert
# Lösung:
# Variables in Coolify setzen und Supervisor nutzt sie automatisch
4. Initialization Scripts
Drei verschiedene Ansätze entwickelt:
- docker-entrypoint.sh - Initialisierung beim Container Start
- init-pocketbase.sh - PocketBase Setup Script
- pb_schema.json - Datenbankstruktur als JSON
5. Coolify Configuration
GitHub App Integration:
- GitHub App erstellt und Repository verbunden
- Automatische Deployments bei Git Push
Build Configuration:
- Build Pack:
Dockerfile(NICHT Nixpacks!) - Keine speziellen Build Commands nötig
Environment Variables (KRITISCH!):
# Diese MÜSSEN in Coolify gesetzt werden:
ORIGIN=http://w848k4ksk88o8w84kcosw488.91.99.221.179.sslip.io
PUBLIC_POCKETBASE_URL=http://localhost:8090
POCKETBASE_ADMIN_EMAIL=till.schneider@memoro.ai
POCKETBASE_ADMIN_PASSWORD=p0ck3tRA1N
Kritische Erkenntnisse
1. Environment Variables sind ESSENTIELL
- Problem: Supervisor kann nicht starten ohne die ENV Variables
- Symptom: Endlosschleife im Container mit Supervisor Error
- Lösung: ALLE benötigten ENV Variables in Coolify UI setzen
2. Docker Build Context
- Problem:
.dockerignorefehlte anfangs - Folge: Unnötige Dateien im Image
- Lösung: Sauberer
.dockerignoreerstellt
3. PocketBase Persistenz
- Wichtig: Volume Mount für
/app/pb_datain Coolify konfigurieren - Sonst: Datenverlust bei jedem Redeploy
4. Supervisor Syntax
- Korrekt:
%(ENV_VARIABLE_NAME)sfür Environment Variables - Wichtig: Supervisor erwartet
ENV_Prefix
5. Health Checks
- Endpoint:
/healtherstellt für Monitoring - Nutzen: Coolify kann App-Status überwachen
Debugging Workflow
- Logs prüfen: Coolify Dashboard → Logs
- Container Status: Prüfen ob Running
- Environment Variables: Verifizieren dass alle gesetzt sind
- Netzwerk: Ports und Domains prüfen
Finale Dateistruktur
uload/
├── Dockerfile # Multi-stage build
├── docker-compose.yml # Lokales Testing
├── supervisord.conf # Process Management
├── docker-entrypoint.sh # Container Initialization
├── .dockerignore # Build Optimierung
├── .env.example # Environment Template
├── .env.production.example # Production Template
├── backend/
│ ├── pb_schema.json # Database Schema
│ ├── init-pocketbase.sh # PocketBase Setup
│ └── pb_migrations/ # Migrations (optional)
├── src/
│ └── routes/
│ └── health/
│ └── +server.ts # Health Check Endpoint
└── DEPLOYMENT.md # Deployment Guide
Zeitaufwand
- Repository Fixes: 30 Minuten (Dependencies, Git Issues)
- Docker Setup: 45 Minuten (Multi-stage Build, PocketBase Integration)
- Supervisor Config: 20 Minuten (Environment Variables Issue)
- Coolify Setup: 15 Minuten (GitHub App, ENV Variables)
- Debugging: 30 Minuten (Logs analysieren, Fixes)
Total: ~2.5 Stunden
Kommandos für Wartung
Lokales Testing:
docker-compose up --build
Deployment:
git add .
git commit -m "Update"
git push
# Coolify deployed automatisch
PocketBase Admin:
http://[domain]/_/
Login: till.schneider@memoro.ai
Health Check:
curl http://[domain]/health
Was gut funktioniert hat
✅ Multi-Container in einem Image: Supervisor managed beide Services perfekt ✅ Auto-Init: PocketBase Setup läuft automatisch beim ersten Start ✅ GitHub Integration: Push = Deploy ✅ Health Monitoring: Endpoint zeigt Status beider Services
Was wir anders machen würden
- Environment Variables zuerst: Direkt in Coolify konfigurieren
- Simpler Start: Erst ohne docker-entrypoint.sh
- Logging: Mehr Debug-Output in Scripts
- Documentation: ENV Requirements prominenter dokumentieren
Kosten
- Hetzner VPS CX21: 5,83€/Monat
- Domain: Kostenlos via sslip.io
- SSL: Kostenlos via Coolify/Let's Encrypt
Performance
- Build Zeit: ~30 Sekunden
- Deployment: ~1 Minute
- Container Start: ~5 Sekunden
- Memory Usage: ~200MB
- CPU Usage: <5% idle
Domain Setup (ulo.ad)
DNS Konfiguration
Type: A
Name: @
Value: 91.99.221.179
TTL: 3600
Coolify Domain Setup
- Add Domain:
ulo.adundwww.ulo.ad - SSL: Generate Certificate + Force HTTPS
- Environment Variables UPDATE (KRITISCH!):
ORIGIN=https://ulo.ad PUBLIC_POCKETBASE_URL=https://ulo.ad/api
Proxy Rules für PocketBase
location /api {
rewrite ^/api/(.*) /$1 break;
proxy_pass http://localhost:8090;
}
location /_/ {
proxy_pass http://localhost:8090;
}
Finale URLs
- Production: https://ulo.ad
- Admin Panel: https://ulo.ad/_/
- API: https://ulo.ad/api
- Health: https://ulo.ad/health
Nächste Schritte
- Eigene Domain konfigurieren (ulo.ad)
- SSL aktivieren (Let's Encrypt via Coolify)
- Backup Strategie implementieren
- Monitoring erweitern
- CI/CD Pipeline mit Tests
Hilfreiche Links
Kontakt & URLs
Temporäre URLs (vor Domain Setup)
- Temp URL: http://w848k4ksk88o8w84kcosw488.91.99.221.179.sslip.io
- Server IP: 91.99.221.179
- Coolify: http://91.99.221.179:8000
Production URLs (ulo.ad)
- Website: https://ulo.ad
- PocketBase Admin: https://ulo.ad/_/
- API Endpoint: https://ulo.ad/api
- Health Check: https://ulo.ad/health
- Admin Login: till.schneider@memoro.ai
Dokumentiert am 13. August 2024 nach erfolgreichem Deployment Updated mit Domain Setup für ulo.ad