135 lines
4.7 KiB
Markdown
135 lines
4.7 KiB
Markdown
|
|
# 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 |
|
|||
|
|
| **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 für beide Hostnamen auf den Reverse-Proxy.
|
|||
|
|
|
|||
|
|
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` | Push `develop`/`main`, PR `develop` | Backend-Tests isoliert SQLite im Container plus Frontend-Build. Keine Live-Provider-Keys. |
|
|||
|
|
|
|||
|
|
Prod nur über Merge `develop` → `main`, kein direkter Prod-Schreibzugriff.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 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, `KANSHO_ENV=production` ohne Klartext-Detect.
|
|||
|
|
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.
|