Basis: Certvia dev@a48c5fb als Fundament für Craftvia
Unveränderter Stand von certvia/dev (a48c5fb) plus Craftvia-Spezifikation und Brandbook unter docs/craftvia/. ISMS-Module werden im Folgecommit entfernt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
# Prod-Deploy via vorgebaute Images (Plan B) — Runbook
|
||||
|
||||
> **Warum:** Der direkte Build auf dem Prod-Coolify läuft in den Deployment-Timeout
|
||||
> (~1 h; Ursache ist Coolifys Build-Pfad — u. a. die ~265-ARG-Injektion, die den
|
||||
> Layer-Cache bei jedem Deploy bricht → Kaltbau). Lösung: Images **einmal auf einem
|
||||
> leistungsfähigen Host bauen**, in die Registry pushen, und der Prod-Host **zieht nur**.
|
||||
> Ergebnis: Prod-Deploy = Pull + Migrate = Minuten statt Stunde.
|
||||
|
||||
## Topologie (Stand 2026-09-10)
|
||||
|
||||
| Rolle | Host |
|
||||
|---|---|
|
||||
| **Build-Host** (baut + pusht) | `192.168.1.155` — lokales Coolify (= local-gitea-Host), amd64, Docker |
|
||||
| **Registry** | **git.certvia.de** (Gitea Container Registry), Namespace `msolarczek` |
|
||||
| **Prod** (`certvia_prod`, GEFIM live) | **coolify.certvia.de** (eigener Server, ≠ 192.168) |
|
||||
| Quelle | git.certvia.de/msolarczek/certvia, Branch `main` |
|
||||
|
||||
Beteiligte Dateien im Repo:
|
||||
- `docker-compose.coolify.prebuilt.yml` — wie `docker-compose.coolify.yml`, aber die App-Services ziehen `${REGISTRY:-git.certvia.de/msolarczek}/certvia-*:${IMAGE_TAG:-main}` statt zu bauen (`postgres`/`redis` unverändert).
|
||||
- `scripts/build-and-push-images.sh` — baut + pusht die drei Images.
|
||||
|
||||
Service → Image (Dockerfile-Target):
|
||||
- `app` → **certvia-app** (`runner`)
|
||||
- `migrate`, `worker`, `backup-worker`, `incident-inbound-worker`, `garage-provision` → **certvia-migrate** (`migrate`)
|
||||
- `garage` → **certvia-garage** (`garage`)
|
||||
|
||||
## Voraussetzung: Gitea-Token
|
||||
Token in git.certvia.de → Settings → Applications mit Scopes:
|
||||
`read:repository` (Klonen) + `read:package` + `write:package` (Image Push/Pull).
|
||||
|
||||
## Ablauf je Release
|
||||
|
||||
### 1. Auf dem Build-Host (192.168.1.155)
|
||||
```bash
|
||||
docker login git.certvia.de -u msolarczek # Passwort = Token
|
||||
git clone https://msolarczek:<TOKEN>@git.certvia.de/msolarczek/certvia.git cv-build # oder: cd cv-build && git fetch && git pull
|
||||
cd cv-build && git checkout main && git pull
|
||||
ALSO_MAIN=true ./scripts/build-and-push-images.sh # baut+pusht Tag <SHA> UND :main
|
||||
```
|
||||
> **Wichtig:** `ALSO_MAIN=true` setzen → es wird zusätzlich das bewegliche Tag `:main`
|
||||
> gepusht. Coolify zieht per Default `:main` (siehe Gotcha IMAGE_TAG unten).
|
||||
|
||||
### 2. Prod-Host (coolify.certvia.de) einmalig am Registry anmelden
|
||||
```bash
|
||||
docker login git.certvia.de -u msolarczek # Passwort = Token
|
||||
```
|
||||
(oder in der Coolify-UI unter Settings → Docker Registries hinterlegen). Nur beim
|
||||
ersten Mal / nach Token-Wechsel nötig.
|
||||
|
||||
### 3. Coolify (certvia_prod, coolify.certvia.de)
|
||||
- **Configuration → „Docker Compose Location"** = `docker-compose.coolify.prebuilt.yml` (einmalig).
|
||||
- Env unverändert: `RUN_DEMO_SEED=false`, `BOOTSTRAP_ADMIN=false`.
|
||||
- **Redeploy.** Log zeigt Pull der `certvia-*:main` → `migrate` (achte auf neue Migration) → `garage`/`garage-provision` → `app` healthy.
|
||||
|
||||
### 4. Nach dem Deploy — Bestandsmandanten-Migrationen der Fachdaten
|
||||
Nur nötig, wenn eine Änderung Bestandsmandanten betrifft (z. B. der 5×5-Backfill). In
|
||||
Coolify → certvia_prod → Service `backup-worker`/`worker` → Terminal (oder per SSH
|
||||
`docker exec`):
|
||||
```bash
|
||||
npx tsx scripts/backfill-risk-5x5.ts # idempotent, alle Mandanten
|
||||
```
|
||||
|
||||
### 5. Smoke-Test
|
||||
Login → betroffene Modulseiten prüfen (z. B. `/processes`, `/dependencies`).
|
||||
|
||||
## Gotchas (aus dem ersten Live-Lauf gelernt)
|
||||
|
||||
- **`IMAGE_TAG` wird von Coolify NICHT in die Compose-Interpolation gereicht** → die
|
||||
Datei fällt auf `:main` zurück. Deshalb `:main` immer mitpushen (`ALSO_MAIN=true`).
|
||||
SHA-genaues Pinning müsste erst geklärt werden (dann `IMAGE_TAG=<sha>` in Coolify-Env).
|
||||
- **Coolify entfernt die alten Container VOR dem Pull.** Fehlt der Ziel-Tag in der
|
||||
Registry, schlägt der Pull fehl und **prod ist unten**. Also *immer erst* Images
|
||||
(inkl. `:main`) pushen, *dann* Redeploy.
|
||||
- **Klon-403:** Ein reiner Package-Token darf nicht klonen — `read:repository` fehlt.
|
||||
- **Migration-Drift ungefährlich:** `prisma migrate deploy` läuft auch dann sauber (Exit 0),
|
||||
wenn die DB eine angewandte Migration hat, die lokal nicht mehr existiert (empirisch geprüft).
|
||||
- Nach Nutzung Token, der im Klartext (URL/History) auftauchte, **widerrufen**.
|
||||
|
||||
## Rollback
|
||||
Alten Stand deployen: früheres Image-Tag als `:main` retaggen+pushen (auf dem Build-Host)
|
||||
und Redeploy — oder Compose-Location zurück auf `docker-compose.coolify.yml` (Host-Build,
|
||||
langsam) als Notnagel.
|
||||
Reference in New Issue
Block a user