Document remote backend deployment
This commit is contained in:
@@ -7,12 +7,13 @@ Das NSCT-Frontend ist eine **Single-Page-Application (SPA)**, die als statische
|
||||
### Architektur
|
||||
|
||||
```
|
||||
Browser → Caddy (HTTPS/Reverse-Proxy) → Web-Container (Statische Assets) → NSCT-Backend (API)
|
||||
Browser → Caddy (`/` statische SPA, `/api/*` Proxy) → NSCT-Backend auf konfigurierbarem Host
|
||||
```
|
||||
|
||||
- **Build:** SvelteKit mit `@sveltejs/adapter-static` → alle Assets landen in `build/`
|
||||
- **Runtime:** Node 22 Alpine, portiert auf `3000`
|
||||
- **Proxy:** Caddy übernimmt TLS, Security Headers, Compression
|
||||
- **Runtime:** Caddy liefert die statischen Assets auf Port `3000` aus.
|
||||
- **Proxy:** Der äußere Caddy übernimmt TLS, Security Headers, Compression und leitet `/api/*` an `NSCT_API_UPSTREAM` weiter.
|
||||
- **Deployment:** Frontend und Backend können auf getrennten Rechnern laufen; sie benötigen kein gemeinsames Docker-Netzwerk.
|
||||
- **Auth:** API-Key-basiert, persistiert im `localStorage` des Browsers
|
||||
- **UI-Pattern:** Svelte 5 Stores (`writable`), TailwindCSS utility-first, Svelte 5 Runes
|
||||
|
||||
@@ -30,7 +31,7 @@ Browser → Caddy (HTTPS/Reverse-Proxy) → Web-Container (Statische Assets) →
|
||||
|
||||
### Deployment
|
||||
|
||||
Multi-Stage Docker Build (Node 22 Alpine) → statische Assets → Caddy Reverse-Proxy.
|
||||
Multi-Stage Docker Build (Node 22 Alpine) → statische Assets → Caddy-Webserver → Caddy Reverse-Proxy.
|
||||
|
||||
---
|
||||
|
||||
@@ -75,7 +76,15 @@ docker compose up -d
|
||||
curl http://localhost:3000/health
|
||||
```
|
||||
|
||||
Erwartete Antwort: HTTP 200 mit JSON-Payload.
|
||||
Erwartete Antwort: HTTP 200.
|
||||
|
||||
### Backend-Verbindung prüfen
|
||||
|
||||
```bash
|
||||
curl http://localhost/api/health
|
||||
```
|
||||
|
||||
Die Anfrage wird durch Caddy an `${NSCT_API_UPSTREAM}/health` weitergeleitet. Für einen getrennten Backend-Rechner müssen DNS bzw. Firewall den Zugriff des Frontend-Rechners auf dessen API-Port erlauben.
|
||||
|
||||
### Browser öffnen
|
||||
|
||||
@@ -224,9 +233,6 @@ services:
|
||||
dockerfile: Dockerfile
|
||||
container_name: nsct-web
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- NSCT_API_BASE_URL=http://nsct-api:8080
|
||||
- DEFAULT_THEME=dark
|
||||
ports:
|
||||
- "3000:3000" # Direktzugriff (intern)
|
||||
networks:
|
||||
@@ -308,9 +314,10 @@ networks:
|
||||
driver: bridge
|
||||
```
|
||||
|
||||
Bridge-Netzwerk für inter-Container-Kommunikation. Container erreichen sich über ihren Namen als hostname:
|
||||
- Web-Container erreicht Backend über `nsct-api:8080`
|
||||
- Caddy erreicht Web-Container über `web:3000`
|
||||
Das Bridge-Netzwerk verbindet ausschließlich die beiden Frontend-Container.
|
||||
Caddy erreicht den Web-Container über `web:3000`. Das Backend wird nicht über
|
||||
dieses Netzwerk adressiert, sondern über `NSCT_API_UPSTREAM` (DNS-Name oder IP
|
||||
des Backend-Rechners).
|
||||
|
||||
### Resource Limits
|
||||
|
||||
@@ -358,10 +365,9 @@ CMD ["node", "build"]
|
||||
|
||||
**Stage 2 — Runtime:**
|
||||
- Node 22 Alpine (lean, ~70 MB)
|
||||
- Nur `build/` und `node_modules` kopiert (kein Quellcode)
|
||||
- Non-root-User `nsct` (Sicherheit)
|
||||
- Die Build-Stage erzeugt `build/`; die Runtime liefert ausschließlich diese statischen Dateien aus.
|
||||
- Health-Check integriert
|
||||
- Startet SvelteKit mit `node build`
|
||||
- Caddy liefert die SPA einschließlich Fallback für Client-Routen aus.
|
||||
|
||||
### Vite Konfiguration
|
||||
|
||||
@@ -374,7 +380,7 @@ export default defineConfig({
|
||||
host: '0.0.0.0',
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://nsct-api:8080',
|
||||
target: 'http://localhost:8080',
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/api/, '')
|
||||
}
|
||||
@@ -384,8 +390,8 @@ export default defineConfig({
|
||||
```
|
||||
|
||||
- **Port:** 3000, strikte Bindung (`strictPort: true`)
|
||||
- **Dev-Proxy:** `/api/*` wird an `http://nsct-api:8080` geroutet
|
||||
- **Production:** Keine Proxy-Config — API-Calls gehen direkt an `NSCT_API_BASE_URL`
|
||||
- **Dev-Proxy:** `/api/*` wird an ein lokal erreichbares Backend geroutet.
|
||||
- **Production:** API-Calls gehen an `/api/*`; Caddy leitet sie an `NSCT_API_UPSTREAM` weiter.
|
||||
|
||||
### TailwindCSS Konfiguration
|
||||
|
||||
@@ -550,8 +556,8 @@ localStorage.removeItem('nsct-api-key'); // Entfernen
|
||||
|
||||
| Ursache | Diagnose | Lösung |
|
||||
|---|---|---|
|
||||
| Falsche `NSCT_API_BASE_URL` | `curl $NSCT_API_BASE_URL/health` → fail | `.env` anpassen, `docker compose up -d` |
|
||||
| CORS-Probleme (Backend) | Browser-Console: CORS error | Backend CORS-Headers prüfen |
|
||||
| Falscher `NSCT_API_UPSTREAM` | `curl http://localhost/api/health` → fail | Host:Port in `.env` anpassen, `docker compose up -d` |
|
||||
| Netzwerk/Firewall blockiert Backend | `curl http://localhost/api/health` → 502 | DNS, Routing und Firewall zwischen den Rechnern prüfen |
|
||||
| API-Key falsch/ungültig | 401/403 vom Backend | API-Key validieren, neu generieren |
|
||||
| Backend nicht erreichbar | `docker compose logs web` → connection refused | Backend-Container prüfen: `docker ps` |
|
||||
|
||||
@@ -559,7 +565,7 @@ localStorage.removeItem('nsct-api-key'); // Entfernen
|
||||
# Diagnose-Skript
|
||||
docker compose logs web | grep -i error
|
||||
curl -v http://localhost:3000/health
|
||||
docker compose exec web wget -qO- http://nsct-api:8080/health || echo "Backend unreachable"
|
||||
curl -v http://localhost/api/health
|
||||
```
|
||||
|
||||
### Share-Links funktionieren nicht
|
||||
@@ -573,7 +579,7 @@ docker compose exec web wget -qO- http://nsct-api:8080/health || echo "Backend u
|
||||
| Token abgelaufen | Backend gibt 404/410 zurück | Neues Share-Link generieren |
|
||||
| Backend nicht erreichbar | `curl` auf Backend fail | Backend-Container prüfen |
|
||||
| Caddy-Proxy blockiert | Caddy logs zeigen 404 | Caddyfile auf `/share/`-Route prüfen |
|
||||
| Falsche `NSCT_API_BASE_URL` | Frontend kann Share-Endpoint nicht reachen | `.env` überprüfen |
|
||||
| Falscher `NSCT_API_UPSTREAM` | Frontend kann Share-Endpoint nicht erreichen | `.env`, DNS und Firewall prüfen |
|
||||
|
||||
```bash
|
||||
# Share-Token auf Gültigkeit prüfen
|
||||
@@ -720,11 +726,11 @@ Caddy 2.8 mit [`caddymetrics`](https://github.com/mholt/caddymetrics) oder built
|
||||
|
||||
### Pre-Deploy
|
||||
|
||||
- [ ] `.env`-Datei überprüft: `NSCT_API_BASE_URL`, `CADDY_DOMAIN`, `DEFAULT_THEME`
|
||||
- [ ] `.env`-Datei überprüft: `NSCT_API_UPSTREAM`, `CADDY_DOMAIN`
|
||||
- [ ] DNS-Eintrag für `CADDY_DOMAIN` zeigt auf Server-IP
|
||||
- [ ] Ports 80 und 443 im Firewall/Security-Group freigeschaltet
|
||||
- [ ] Caddyfile auf Korrektheit geprüft (Syntax: `docker compose exec caddy caddy validate --config /etc/caddy/Caddyfile`)
|
||||
- [ ] Backend-Container erreichbar: `docker compose exec web wget -qO- http://nsct-api:8080/health`
|
||||
- [ ] Backend vom Frontend-Rechner erreichbar: `curl http://localhost/api/health`
|
||||
- [ ] Git-Status sauber: `git status` → kein uncommitted Code
|
||||
|
||||
### Deploy
|
||||
@@ -807,7 +813,7 @@ docker compose up -d
|
||||
|
||||
2. API-Anfrage (z.B. Research erstellen)
|
||||
→ localStorage.getItem('nsct-api-key')
|
||||
→ POST ${NSCT_API_BASE_URL}/research
|
||||
→ POST /api/v1/research
|
||||
→ Header: X-API-Key: <key>
|
||||
→ Body: { "query": "..." }
|
||||
|
||||
@@ -817,7 +823,7 @@ docker compose up -d
|
||||
→ Polling: pollingActive.set(true) → pollingInterval (5s)
|
||||
|
||||
4. Polling bis COMPLETED/FAILED
|
||||
→ GET ${NSCT_API_BASE_URL}/research/<id>
|
||||
→ GET /api/v1/research/<id>
|
||||
→ X-API-Key: <key>
|
||||
→ Status prüfen: COMPLETED → pollingActive.set(false)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user