# 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änzt `docs/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) **vor** `app` — 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: 1. **Coolify → Keys & Tokens → Private Keys**: SSH-Key generieren (oder beim Anlegen der Ressource „Private Repository (deploy key)“ automatisch). Öffentlichen Key kopieren. 2. **Gitea → Repo `msolarczek/ISMS-Tool` → Settings → Deploy Keys → Add Deploy Key**: Key einfügen, nur Lesezugriff. 3. Repo-URL in Coolify (SSH): `git@gitea-vkbhbn2qdkz5ppk9q4qgb0tn.192.168.1.207.sslip.io:msolarczek/ISMS-Tool.git` ## 2. Ressource anlegen 1. Projekt/Environment wählen → **+ New → Private Repository (deploy key)**. 2. Repo `ISMS-Tool`, **Branch `devops/coolify-testserver`** (nach erfolgreichem Test → `main`). 3. **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` (nicht `localhost`). - `AUTH_SECRET` frisch: `openssl rand -base64 32`. - `AUTH_URL` = exakt die in Schritt 4 vergebene App-Domain (`http://…`). - `MINIO_ROOT_USER/PASSWORD` müssen `S3_ACCESS_KEY/S3_SECRET_KEY` entsprechen. ## 4. Domain & HTTP - Beim Service `app` unter **Domains** die `*.sslip.io`-Domain übernehmen, Schema **`http://`**. - Dieselbe Domain als `AUTH_URL` setzen (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 > (siehe `docs/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_SECRET` und 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.