Keep KANSHO_ENV=production and require an explicit operator flag instead of treating Prod as Development. Promote to Prod only via merge commit on main. Co-authored-by: Cursor <cursoragent@cursor.com>
147 lines
8.5 KiB
Markdown
147 lines
8.5 KiB
Markdown
---
|
||
title: "Kanshō – Runtime, Migrationen und Deploy"
|
||
version: "0.1"
|
||
status: "Arbeitsstand"
|
||
date: "2026-09-07"
|
||
product_family: "Jinkendo"
|
||
document_role: "Technical Chapter / Runtime / Deploy / Migrations"
|
||
parent_document: "technische_zielarchitektur.md"
|
||
---
|
||
# Kanshō – Runtime, Migrationen und Deploy
|
||
|
||
Kanonisches Home für Container-Start, Schema-Evolution und Gitea-Pipelines. Mitai-Referenz: `MIGRATION_DEPLOY_DESIGN_PRINCIPLES.md`, `docker-compose.yml`, `docker-compose.dev-env.yml`, `.gitea/workflows/`.
|
||
|
||
## 1. Umgebungen
|
||
|
||
Muster der Familie: zwei Umgebungen, zwei Branches.
|
||
|
||
| Umgebung | Git-Branch | Rolle |
|
||
|---|---|---|
|
||
| Development | `develop` | Auto-Deploy nach Push |
|
||
| Production | `main` | Auto-Deploy nach Merge |
|
||
|
||
**Status: entschieden** als Betriebsmuster. Host, Pfade, Domains und Ports sind seit 2026-09-07 festgelegt (gleicher Raspberry Pi wie die Schwesterprodukte, eigene Compose-Projekte, keine Mitai-`bodytrack/`-Pfade).
|
||
|
||
Lokale Entwicklung (ohne Docker) verwendet eigene Ports, nicht die Vite-/FastAPI-Defaults und nicht die Ports anderer lokaler Repos:
|
||
|
||
| Dienst | Port | Bindung |
|
||
|---|---|---|
|
||
| Frontend (Vite) | 5188 | `strictPort`, kein Ausweichen |
|
||
| Backend (Uvicorn) | 8018 | explizit |
|
||
|
||
Nicht verwenden: 5173, 5174, 4000, 4001, 8000.
|
||
|
||
Server (Raspberry Pi 5, `192.168.2.49`):
|
||
|
||
| | Development | Production |
|
||
|---|---|---|
|
||
| Branch | `develop` | `main` |
|
||
| Host-Pfad | `/home/lars/docker/kansho-dev` | `/home/lars/docker/kansho` |
|
||
| Domain | `dev.kansho.jinkendo.de` | `kansho.jinkendo.de` |
|
||
| Frontend-Port | 3096 | 3006 |
|
||
| Backend-Port | 8096 | 8005 |
|
||
| Postgres | eigene Instanz `kansho_dev`, nicht nach außen | eigene Instanz `kansho`, nicht nach außen |
|
||
| Compose | `docker-compose.dev-env.yml` | `docker-compose.yml` |
|
||
|
||
Operative Schritte: `docs/DEPLOYMENT.md`. Gitea intern: `http://192.168.2.144:3000/Lars/Kansho.git`.
|
||
|
||
## 2. Container
|
||
|
||
Docker Compose mit mindestens:
|
||
|
||
- Frontend (Nginx + gebündelte PWA in Prod; Vite-Dev optional lokal)
|
||
- Backend (FastAPI)
|
||
- PostgreSQL 16
|
||
|
||
Secrets und SMTP nur in Server-`.env`, nicht im Repository. Vorlage: `.env.example`.
|
||
|
||
Watchtower oder gleichwertiges Image-Update: Mitai-Betrieb, für Kanshō **später prüfen**.
|
||
|
||
## 3. Schema-Migrationen
|
||
|
||
**Status: entschieden** (Muster)
|
||
|
||
1. Nummerierte SQL-Dateien `backend/migrations/XXX_*.sql`.
|
||
2. Tracking-Tabelle `schema_migrations`.
|
||
3. Startup: Postgres ready → Migrationen → App-Prozess.
|
||
4. Idempotenz wo möglich (`IF NOT EXISTS`).
|
||
5. Kein automatisches Schema-Downgrade.
|
||
|
||
Greenfield-Basis analog Mitai `schema.sql` ist zulässig. Änderungen danach nur über nummerierte Migrationen.
|
||
|
||
Fail-fast beim Start, wenn Migrationen scheitern. Kein stilles Weiterlaufen mit Drift.
|
||
|
||
## 4. Gitea CI/CD
|
||
|
||
Mitai-Pipeline als Vorlage:
|
||
|
||
```text
|
||
push develop → deploy-dev.yml → compose build/up → Healthcheck
|
||
successful Dev deploy → test.yml (pytest on kansho_test, Live-Smoke /api/health, Frontend-Build)
|
||
merge --no-ff develop in main → push main → deploy-prod.yml
|
||
```
|
||
|
||
**Status: entschieden.** Workflows liegen unter `.gitea/workflows/` (`deploy-dev.yml`, `deploy-prod.yml`, `test.yml`). Muster analog Kairo: `git reset --hard`, `build --no-cache`, Health `GET /api/health`.
|
||
|
||
**Additiv 2026-09-07 (Qualitätssystem):** Backend-Runner ist pytest (`backend/pytest.ini`, `backend/tests/conftest.py`). Gitea startet die Suite erst nach erfolgreichem Dev-Deploy (`workflow_run` auf `Deploy Development`), nicht parallel zum Image-Build. Destruktive Tests bleiben auf `kansho_test`. Zusätzlich ein nicht-schreibender Smoke gegen die laufende Dev-API (`kansho_dev`, nur `/api/health`). Öffentliche URLs nach Host-Nginx/TLS: `https://dev.kansho.jinkendo.de` und `https://kansho.jinkendo.de`. LAN-Ports 3096/8096 und 3006/8005 bleiben die Compose-Publish-Ziele.
|
||
|
||
Kanshō-Repo liegt auf Gitea (`Lars/Kansho`). HTTPS-Push ist eingerichtet. Der Pi-Runner (`ubuntu-latest`) ist derselbe wie bei Mitai/Shinkan/Kairo.
|
||
|
||
## 5. Was Deploy nicht übernimmt
|
||
|
||
- Blue-Green oder Multi-Region
|
||
- Automatisches Rollback der Datenbank
|
||
- Mitai-Verzeichnisnamen auf dem Pi
|
||
- Fachliche Datenberechnungen
|
||
|
||
## 6. Entscheidungsstand
|
||
|
||
| Thema | Stand | Status |
|
||
|---|---|---|
|
||
| Compose + Postgres + nummerierte SQL-Migrationen | ja | entschieden |
|
||
| develop → Dev, main → Prod | ja | entschieden |
|
||
| Ports/Domains/Hostpfade | lokal 5188/8018; Server 3096/8096 und 3006/8005; `*.kansho.jinkendo.de` | entschieden 2026-09-07 |
|
||
| Host | gleicher Raspberry Pi wie Mitai/Shinkan/Kairo, eigene Compose-Projekte `kansho` / `kansho-dev` | entschieden 2026-09-07 |
|
||
| Postgres | eigene Instanz je Umgebung (`kansho` / `kansho_dev`), kein Shared-Schema | entschieden 2026-09-07 |
|
||
| Gitea Workflows | `.gitea/workflows/` analog Kairo | entschieden 2026-09-07 |
|
||
| Auto-Rollback | nein | verworfen |
|
||
| Dual-Backend | SQLite nur Windows-App ohne Docker; Server Dev+Prod PostgreSQL. pytest auf der Dev-Instanz in DB `kansho_test` neben `kansho_dev` (keine dritte Instanz) | entschieden 2026-09-07, pytest 2026-09-07 |
|
||
| Öffentliche URLs | `https://dev.kansho.jinkendo.de` / `https://kansho.jinkendo.de` (Host-Nginx + Let's Encrypt; Einrichtung parallel) | entschieden 2026-09-07 |
|
||
| Urlaubs-Laptop ohne Docker/SQLite | Phase A auf dem Heimrechner restored | dokumentiert 2026-09-07 |
|
||
| Transfer vor Postgres | SQLite-Restore auf dem Heimrechner zuerst | entschieden als Reihenfolge |
|
||
|
||
## 7. Offene Fragen
|
||
|
||
1. ~~Läuft Kanshō auf demselben Raspberry-Pi-Host wie Mitai, mit eigenen Compose-Projekten?~~ **Entschieden:** ja, Pi `192.168.2.49`, Pfade `/home/lars/docker/kansho` und `kansho-dev`.
|
||
2. ~~Gemeinsames oder separates Postgres?~~ **Entschieden:** eigene Instanz je Umgebung, kein Shared-Schema mit Mitai.
|
||
3. Backup-Rhythmus nach dem Prod-Cutover. Die Urlaubs-SQLite-Restore auf dem Heimrechner (Welle 1) ist die Übung für den bestehenden Datenbestand. Postgres-Dump plus Medien: `docs/DEPLOYMENT.md` und `scripts/backup-postgres.sh`. Erste Restore-Übung auf Dev vor dem Prod-Import.
|
||
|
||
### 7.1 Lokales Backup für die Urlaubs-Testphase (2026-08-25)
|
||
|
||
Kein Ersatz für Produktions-Backup, Docker oder Verschlüsselung.
|
||
|
||
- Erzeugen: `.\scripts\backup-local.ps1 create` oder `python backend\local_backup.py create --out <pfad>`
|
||
- Standardziel: `local-backups/` (gitignoriert)
|
||
- Wiederherstellen: `.\scripts\backup-local.ps1 restore -Archive <pfad> -Confirm`; bestehender Stand nur mit `--replace` nach automatischem Sicherheitsbackup
|
||
- SQLite-Backup-API, Journalmedien, Manifest mit Checksummen. Keine `.env` oder Keys. Das Archiv kann persönliche unverschlüsselte Daten enthalten.
|
||
|
||
### 7.2 Transfer Laptop → Heim-Entwicklung und Server (2026-09-07)
|
||
|
||
Die Urlaubsinstanz lief ohne Docker auf SQLite (`backend/data/kansho.sqlite`, Ports 5188/8018).
|
||
|
||
**Reihenfolge entschieden:** zuerst Kontinuität (Clone + SQLite-Restore + Smoke), danach Betriebsrahmen (Compose, Postgres 16, Gitea-Runner). Dual-Backend: SQLite nur für die Windows-App ohne Docker; Postgres im Container (zwei Instanzen: Dev `kansho_dev`, Prod `kansho`). Die Test-Suite nutzt dieselbe Dev-Postgres, Datenbank `kansho_test` neben `kansho_dev`, weil sie das Schema zurücksetzt. Ein direkter Sprung „Laptop-SQLite nach Prod-Postgres“ ohne Zwischen-Restore ist verworfen. Import: `sqlite_to_postgres.py --confirm`, zuerst Dev, dann Prod.
|
||
|
||
**Additiv 2026-09-07 (Transportweg):** Auf dem Urlaubs-Laptop dürfen weder USB-Stick noch NAS verbunden werden. Der einzige Weg für Datenbank und persönliche Journaldaten ist das **selbst gehostete** Gitea (`gitea.stommer.de`, nur eigene Infrastruktur). Das ist eine einmalige Transportentscheidung, kein Produktregelwechsel: Provider, OpenRouter und öffentliche Remotes bleiben ausgeschlossen. Provider-Keys und `backend/.env` bleiben **außerhalb** Git.
|
||
|
||
Transportartefakt 2026-09-07: `transfer/kansho-laptop-20260907.zip` (SHA256 `EBF7455D5688588E8C6E50C05D16200CE191D79FB7CEACDBA9C25460B7497B07`). Nach erfolgreichem Restore auf dem Heimrechner das Verzeichnis `transfer/` aus dem Arbeitsbaum entfernen. Die Git-Historie behält das Zip.
|
||
|
||
Kanonisches Session-Handover: `environment_handover.md`. Aufträge: `../../work_orders/laptop_closeout.md`, `../../work_orders/home_environment_setup.md`. Betrieb: `docs/DEPLOYMENT.md`.
|
||
|
||
Compose, Dockerfiles, `.gitea/workflows/` und der Postgres-Adapter liegen im Repository. Mitai unter `C:\Dev\mitai-jinkendo` bleibt Muster, nicht Quelle für Ports oder `bodytrack/`-Pfade.
|
||
|
||
## 8. Querverweise
|
||
|
||
- Technisch: `product_frame_and_stack.md`, `security.md`, `environment_handover.md`, `mvp_implementation.md` §1
|
||
- Fachlich: Offline und Sync bleiben `memory_storage_and_offline.md`; Deploy löst Offline nicht.
|
||
- Mitai: `MIGRATIONS.md`, `.gitea/workflows/`
|