Kansho/docs/DEPLOYMENT.md

136 lines
5.2 KiB
Markdown
Raw Normal View History

# Deployment – Kanshō
**Stand:** 2026-09-07
**Server:** Raspberry Pi 5 (`192.168.2.49`) — gleicher Host wie Mitai/Shinkan/Kairo, **eigene** Compose-Projekte
**Runner:** Gitea Actions (`/home/lars/gitea-runner/`)
**Repo:** `http://192.168.2.144:3000/Lars/Kansho.git`
Kanonische Runtime-Entscheidungen: `docs/architecture/technical/runtime_and_deploy.md`.
Datenübernahme SQLite → Postgres: `backend/sqlite_to_postgres.py` (Probe auf Kopie, `--confirm`).
---
## Port- und Pfad-Übersicht
| | Production | Development |
|---|------------|-------------|
| **Git-Branch** | `main` | `develop` |
| **Server-Verzeichnis** | `/home/lars/docker/kansho` | `/home/lars/docker/kansho-dev` |
| **Frontend-Port** | 3006 | 3096 |
| **Backend-Port** | 8005 | 8096 |
| **PostgreSQL** | nur Compose-Netz, DB `kansho` | nur Compose-Netz, DB `kansho_dev` |
| **Domain** | kansho.jinkendo.de | dev.kansho.jinkendo.de |
| **Öffentliche URL** | https://kansho.jinkendo.de | https://dev.kansho.jinkendo.de |
| **Compose** | `docker-compose.yml` | `docker-compose.dev-env.yml` |
Prod-Frontend ist **3006**, nicht 3005: auf dem Pi lauscht Bookstack bereits auf `0.0.0.0:3005`. Dev 3096/8096 und Prod-API 8005 waren frei.
Lokal ohne Docker bleibt Windows: Frontend **5188**, Backend **8018**, SQLite unter `backend/data/`.
---
## Einmalige Server-Einrichtung
```bash
mkdir -p /home/lars/docker/kansho /home/lars/docker/kansho-dev
cd /home/lars/docker/kansho-dev
git clone http://192.168.2.144:3000/Lars/Kansho.git .
git checkout develop
cp .env.example .env
# DB_PASSWORD und Provider-Keys setzen
cd /home/lars/docker/kansho
git clone http://192.168.2.144:3000/Lars/Kansho.git .
git checkout main
cp .env.example .env
# Prod-DB_PASSWORD und Provider-Keys setzen
```
Host-nginx: `nginx/kansho.conf` und `nginx/kansho-dev.conf` nach `/etc/nginx/sites-available/`, dann `nginx/certbot-setup.sh`. DNS A/AAAA für `dev.kansho.jinkendo.de` und `kansho.jinkendo.de` auf den Reverse-Proxy. Bis TLS steht, bleibt der LAN-Zugriff über die Publish-Ports.
Gitea: Actions aktivieren. Derselbe Pi-Runner wie die Schwesterprodukte (`ubuntu-latest`).
Watchtower bleibt aus.
---
## Gitea Actions
| Workflow | Trigger | Zweck |
|----------|---------|--------|
| `deploy-dev.yml` | Push `develop` | Deploy nach `/home/lars/docker/kansho-dev`, Health `localhost:8096` |
| `deploy-prod.yml` | Push `main` | Deploy nach `/home/lars/docker/kansho`, Health `localhost:8005` |
| `test.yml` | nach erfolgreichem `Deploy Development` | pytest auf `kansho_test`, nicht-schreibender Smoke gegen die laufende Dev-API, Frontend-Build. Keine Live-Provider-Keys. |
Prod nur über Merge-Commit `develop` → `main` (`git merge --no-ff develop` auf `main`), danach Push von `main`. Kein Fast-Forward, kein direkter Commit auf `main`, kein manuelles `git pull` auf dem Prod-Checkout. Gitea (`deploy-prod.yml`) ist der einzige Prod-Schreibpfad für Code.
---
## Datenübernahme (persönlich, Klasse A/B)
1. Phase-A-SQLite auf dem Heimrechner ist führend, bis der Dev-Import grün ist.
2. Schema auf der Zielinstanz durch normalen Container-Start anlegen (leeres Postgres).
3. Import auf **Dev zuerst**:
```bash
# Zip oder laufende SQLite + Medien in den Dev-Container legen, dann:
docker compose -f docker-compose.dev-env.yml exec -T backend \
python sqlite_to_postgres.py --confirm \
--sqlite /tmp/kansho.sqlite \
--media-src /tmp/media \
--media-dest /app/data/media
```
Windows-Vorbereitung (Kopie, nicht das einzige Backup):
```powershell
.\scripts\backup-local.ps1 create
# Archiv prüfen, dann SQLite+Medien auf den Pi kopieren — nicht nach Gitea.
```
4. Abnahme Dev: Profilanzahl, Journal-Days/Entries, Messages, ein Medien-GET, Gateway fail-closed. Production ohne `KANSHO_ALLOW_REMOTE_DETECT` blockiert Klartext-Detect; der Operator-Übergang bis Ollama ist explizit und dokumentiert (`guardrails.md` §22.3).
5. Erst dann derselbe Import nach Prod (`--confirm`, leeres Volume). `--replace` nur auf einer bewussten Kopie.
`debug.persist_traces` nach dem Import prüfen.
---
## Postgres-Backup (Server)
Kein Ersatz durch `backup-local.ps1` (das bleibt der SQLite-Weg).
```bash
# Dump
cd /home/lars/docker/kansho
docker compose exec -T postgres pg_dump -U kansho kansho > "/home/lars/backups/kansho-$(date -u +%Y%m%d).sql"
# Medienvolume
docker run --rm -v kansho_kansho-media:/src -v /home/lars/backups:/dst alpine \
tar -C /src -czf /dst/kansho-media-$(date -u +%Y%m%d).tgz .
```
Restore-Übung vor dem ersten Prod-Dialogbestand nach dem Cutover wiederholen. Dump und Medien nicht an Provider und nicht in öffentliche Remotes.
---
## Manuelles Deploy
```bash
# Development
cd /home/lars/docker/kansho-dev
git fetch origin develop && git reset --hard origin/develop
docker compose -f docker-compose.dev-env.yml build --no-cache backend frontend
docker compose -f docker-compose.dev-env.yml up -d --wait
curl -sf http://localhost:8096/api/health
# Production
cd /home/lars/docker/kansho
git fetch origin main && git reset --hard origin/main
docker compose build --no-cache backend frontend
docker compose up -d --wait
curl -sf http://localhost:8005/api/health
```
Laptop-Checkout nach erfolgreichem Heim-Restore und Dev-Import nur noch Archiv. Keine parallelen Schreibzugriffe auf denselben persönlichen Bestand.