- docker-compose.coolify.yml: Coolify-taugliche Variante (kein host-port, Env via Coolify-Variablen, migrate-Init-Job vor app, app-Healthcheck) - .env.coolify.example: Referenz der Coolify-Env-Variablen (nur Platzhalter) - docs/DEPLOY-COOLIFY.md: Runbook (Gitea-Deploy-Key, Ressource, Env, Domain, Seed) - .gitignore: .env.coolify.example whitelisten Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3.7 KiB
Deployment: Testserver via Coolify (intern)
Zielumgebung: interner Coolify-Host (
192.168.1.207), Docker-Compose-Stack, HTTP über eine*.sslip.io-Domain (kein öffentliches TLS). Ergänztdocs/HANDOVER-DEVOPS.md. Deploy-Datei:docker-compose.coolify.yml.
Architekturüberblick (Coolify)
- Coolify deployt den Compose-Stack aus diesem Repo und übernimmt Reverse-Proxy + Routing — die App wird nicht per Host-Port exponiert.
- Services:
migrate(Init-Job) →app(Next.js standalone) +postgres(pgvector),redis,minio. - Migrationen laufen als eigener Init-Job
migrate(prisma migrate deploy, builder-Image) vorapp— der App-Container migriert selbst nicht. - Secrets/Config kommen aus den Coolify-Env-Variablen (Referenz:
.env.coolify.example), nicht aus einer committeten.env.
1. Gitea mit Coolify verbinden (Deploy Key)
SSH ist erreichbar (git@…sslip.io:22), daher Deploy-Key:
- Coolify → Keys & Tokens → Private Keys: SSH-Key generieren (oder beim Anlegen der Ressource „Private Repository (deploy key)“ automatisch). Öffentlichen Key kopieren.
- Gitea → Repo
msolarczek/ISMS-Tool→ Settings → Deploy Keys → Add Deploy Key: Key einfügen, nur Lesezugriff. - Repo-URL in Coolify (SSH):
git@gitea-vkbhbn2qdkz5ppk9q4qgb0tn.192.168.1.207.sslip.io:msolarczek/ISMS-Tool.git
2. Ressource anlegen
- Projekt/Environment wählen → + New → Private Repository (deploy key).
- Repo
ISMS-Tool, Branchdevops/coolify-testserver(nach erfolgreichem Test →main). - Build Pack: Docker Compose, Compose Location:
docker-compose.coolify.yml.
3. Environment-Variablen
Werte aus .env.coolify.example in Coolify eintragen. Kritisch:
- Hostnamen = Compose-Service-Namen:
postgres,redis,minio(nichtlocalhost). AUTH_SECRETfrisch:openssl rand -base64 32.AUTH_URL= exakt die in Schritt 4 vergebene App-Domain (http://…).MINIO_ROOT_USER/PASSWORDmüssenS3_ACCESS_KEY/S3_SECRET_KEYentsprechen.
4. Domain & HTTP
- Beim Service
appunter Domains die*.sslip.io-Domain übernehmen, Schemahttp://. - Dieselbe Domain als
AUTH_URLsetzen (sonst schlägt der NextAuth-Login fehl).
5. Persistenz
Named Volumes müssen als Persistent Storage erkannt sein — v. a. pgdata (sonst Datenverlust bei Redeploy). Ebenso miniodata, redisdata.
6. Deploy
Deploy starten. Reihenfolge: postgres (healthy) → migrate (läuft einmalig durch) → app (startet erst nach erfolgreichem Migrate). Logs von migrate/app bei Fehlern prüfen.
7. Demo-Admin anlegen (einmalig, Testserver)
Der Demo-Seed läuft nicht automatisch. Im Coolify-Terminal des migrate-Containers (builder-Image, hat tsx):
npx tsx prisma/seed.ts
Login danach: admin@demo.example / Demo1234!.
Produktiv: kein Demo-Seed. Stattdessen einmaliger Bootstrap des Plattform-Admins (
provisionTenant({ admin.isPlatformAdmin: true })) — Skript noch zu erstellen (siehedocs/HANDOVER-DEVOPS.md§4).
8. Smoke-Test
Über die App-Domain: Login, Admin-Konsole, eine Modul-Seite.
Redeploy / Migrationen-Nachziehen
Jeder Coolify-Redeploy baut neu und lässt migrate erneut laufen (migrate deploy ist idempotent — nur neue Migrationen werden angewandt). App startet erst nach erfolgreichem Migrate.
Von Test zu Produktiv (Delta)
AUTH_SECRETund DB-/MinIO-Passwörter neu/aus Secret-Store; eigene Domain + gültiges TLS.- Kein Demo-Seed; Erst-Superadmin per Bootstrap-Skript.
- Backups (
pg_dump/Volume-Snapshots) + Restore-Test, Monitoring/Alerting. - Ggf. ≥ 2
app-Replicas hinter dem Coolify-Proxy.