175 lines
7.1 KiB
Markdown
175 lines
7.1 KiB
Markdown
<!-- status: canonical -->
|
|
<!-- lastReviewed: 2026-05-28 -->
|
|
|
|
# Deployment-Infrastruktur
|
|
|
|
## Hosting-Provider
|
|
|
|
Infomaniak Public Cloud (OpenStack) unter dem Dach-Account **PowerOnUniverse** (ID 17397).
|
|
|
|
Horizon Dashboard: `https://api.pub1.infomaniak.cloud/horizon`
|
|
|
|
## Projektstruktur
|
|
|
|
Jeder Service-Bereich ist ein eigenes OpenStack-Projekt mit eigenem Netzwerk, eigenen Security Groups, eigenen Floating IPs. Die Kommunikation zwischen Projekten laeuft ueber oeffentliche Floating IPs.
|
|
|
|
| Projekt | OpenStack-ID | Zweck |
|
|
|---|---|---|
|
|
| **Porta** | PCP-OUJTOXY | Plattform-Kern (Frontend, Backend, DB) |
|
|
| **Service-LLM** | PCP-MPXPVCR | Private LLM (Ollama + Flask, GPU) |
|
|
| **Service-Teamsbot** | PCP-KO2UYXT | Teams-Browser-Bot |
|
|
|
|
## Naming Convention
|
|
|
|
### Schema
|
|
|
|
```
|
|
{bereich}-{env}-{komponente}
|
|
```
|
|
|
|
- **bereich:** `porta` (Plattform-Kern) oder `service` (eigenstaendiger Service)
|
|
- **env:** `main` (Produktion) oder `int` (Integration)
|
|
- **komponente:** Forgejo-Repo-Name oder `db`
|
|
|
|
### Regeln
|
|
|
|
1. Alles fuer PORTA laeuft im Projekt **Porta** mit:
|
|
- `porta-main-<repo|db>` fuer alle Produktions-Komponenten
|
|
- `porta-int-<repo|db>` fuer alle Integrations-Komponenten
|
|
|
|
2. Alle eigenstaendigen Services laufen je als **separates Projekt** mit:
|
|
- `service-main-<repo>` fuer Produktion
|
|
- `service-int-<repo>` fuer Integration (falls vorhanden)
|
|
|
|
### Instanzen
|
|
|
|
#### Projekt: Porta (PCP-OUJTOXY)
|
|
|
|
| Instanzname | Env | Komponente | Flavor | Intern IP | Floating IP | DNS |
|
|
|---|---|---|---|---|---|---|
|
|
| `porta-main-ui-nyla` | main | Frontend (React/Vite) | a2-ram4-disk20-perf1 | 10.20.0.92 | 37.156.43.5 | `porta.poweron.swiss` |
|
|
| `porta-main-platform-core` | main | Backend (FastAPI) | a2-ram4-disk50-perf1 | 10.20.0.197 | 83.228.234.207 | `api.poweron.swiss` |
|
|
| `porta-main-db` | main | PostgreSQL + pgvector | a2-ram4-disk80-perf1 | 10.20.0.21 | 37.156.40.141 | `db.poweron.swiss` |
|
|
| `porta-int-ui-nyla` | int | Frontend (React/Vite) | a2-ram4-disk20-perf1 | 10.20.0.182 | 37.156.41.74 | `porta-int.poweron.swiss` |
|
|
| `porta-int-platform-core` | int | Backend (FastAPI) | a2-ram4-disk50-perf1 | 10.20.0.74 | 37.156.43.14 | `api-int.poweron.swiss` |
|
|
| `porta-int-db` | int | PostgreSQL + pgvector | a2-ram4-disk80-perf1 | 10.20.0.175 | 37.156.42.67 | `db-int.poweron.swiss` |
|
|
|
|
Key Pair: `ida-laptop` (alle Instanzen)
|
|
|
|
#### Projekt: Service-LLM (PCP-MPXPVCR)
|
|
|
|
| Instanzname | Env | Komponente | Flavor | DNS / IP |
|
|
|---|---|---|---|---|
|
|
| `service-main-llm-private` | main | Ollama + FastAPI (Vision-LLM) | GPU L4 (24 GB VRAM), 8 vCPU, 16 GB RAM, 150 GB | `llm.poweron.swiss` / `83.228.200.109` (Port 8000, HTTPS) |
|
|
|
|
**Geplante Migration → FireStorm (Zug/Zuerich):**
|
|
|
|
| Anbieter | Produkt | GPU | VRAM | CPU | RAM | Storage | Preis |
|
|
|---|---|---|---|---|---|---|---|
|
|
| FireStorm ISP | GPU Pro | RTX PRO 6000 Blackwell Max-Q | 96 GB GDDR7 | AMD Threadripper 3970X (32C/64T) | 256 GB DDR4 ECC | 8 TB NVMe RAID 10 | CHF 749/Mt. + CHF 1'900 Setup |
|
|
|
|
Status: Code vorbereitet (Modell-Definitionen in `aicorePluginPrivateLlm.py`), Hardware noch zu bestellen. DNS-Umschaltung `llm.poweron.swiss` bei Migration.
|
|
|
|
#### Projekt: Service-Teamsbot (PCP-KO2UYXT)
|
|
|
|
| Instanzname | Env | Komponente | Flavor | Floating IP | DNS |
|
|
|---|---|---|---|---|---|
|
|
| `service-main-teams-browser-bot` | main | Docker + Playwright/Chrome | a2-ram4-disk20 | 179.237.73.4 | `teamsbot.poweron.swiss` |
|
|
|
|
Key Pair: `teamsbot-deploy-key`
|
|
|
|
## Deployment-Patterns
|
|
|
|
### VM-Grundkonfiguration (bei Neuinstallation)
|
|
|
|
Auf jeder neuen VM (UI + Backend) nach Erstprovisionierung:
|
|
|
|
```bash
|
|
# needrestart: nur melden, nicht automatisch Services neustarten.
|
|
# Verhindert, dass unattended-upgrades laufende Services (nginx, gateway)
|
|
# waehrend eines apt-Upgrades killt, wenn DNS kurzzeitig nicht verfuegbar ist.
|
|
echo '$nrconf{restart} = '"'"'l'"'"';' | sudo tee /etc/needrestart/conf.d/99-no-auto-restart.conf
|
|
```
|
|
|
|
**Hintergrund:** `unattended-upgrades` aktualisiert OS-Pakete naechtlich. Dabei startet `systemd-networkd` kurz neu (DNS-Ausfall). Wenn `needrestart` gleichzeitig nginx restartet, schlaegt `proxy_pass`-DNS-Aufloesung fehl → nginx crasht und bleibt down. Mit `'l'` (list-only) werden nur betroffene Services gemeldet; der Restart erfolgt kontrolliert beim naechsten Deployment.
|
|
|
|
### Porta (git pull + systemd restart)
|
|
|
|
Deploy-Workflow: `.forgejo/workflows/main_porta-main-platform-core.yml` in `platform-core`
|
|
|
|
1. Forgejo Actions Runner verbindet per SSH auf die VM
|
|
2. `git fetch origin main && git reset --hard origin/main`
|
|
3. `pip install -r requirements.txt`
|
|
4. `sudo systemctl restart gateway`
|
|
|
|
### Private LLM (rsync + systemd restart)
|
|
|
|
Deploy-Workflow: `.github/workflows/deploy.yml` in `service-llm-private`
|
|
|
|
1. GitHub Actions (noch nicht migriert auf Forgejo) verbindet per SSH
|
|
2. `rsync` des Codes nach `/opt/ollama-webapp/app/`
|
|
3. `pip install -r requirements.txt`
|
|
4. `sudo systemctl restart ollama-webapp`
|
|
|
|
### Teams-Bot (rsync + docker compose, geplant)
|
|
|
|
Deploy-Workflow: `.forgejo/workflows/deploy.yml` in `service-teams-browser-bot`
|
|
|
|
1. Forgejo Actions Runner verbindet per SSH auf die VM
|
|
2. `rsync` des Codes nach `/opt/teamsbot/`
|
|
3. `docker compose build && docker compose up -d`
|
|
4. Health-Check auf Port 4100
|
|
|
|
## DB-Setup bei neuer Installation
|
|
|
|
Bei einer neuen DB-Instanz (`porta-*-db`) muessen folgende Schritte ausgefuehrt werden:
|
|
|
|
### 1. pgvector Extension installieren (OS-Package)
|
|
|
|
SSH auf die DB-VM (via API-Server als Jump-Host, da DB-VMs kein externes SSH haben):
|
|
|
|
```bash
|
|
# Vom API-Server aus:
|
|
ssh -i /tmp/ida-laptop.pem ubuntu@<DB_INTERNAL_IP> bash << 'EOF'
|
|
echo 'deb http://apt.postgresql.org/pub/repos/apt jammy-pgdg main' | sudo tee /etc/apt/sources.list.d/pgdg.list
|
|
wget -qO- https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo tee /etc/apt/trusted.gpg.d/pgdg.asc > /dev/null
|
|
sudo apt update -qq
|
|
sudo apt install -y postgresql-14-pgvector
|
|
sudo systemctl restart postgresql
|
|
EOF
|
|
```
|
|
|
|
### 2. Extension in Datenbanken aktivieren
|
|
|
|
```bash
|
|
ssh -i /tmp/ida-laptop.pem ubuntu@<DB_INTERNAL_IP> bash << 'EOF'
|
|
sudo -u postgres psql -d poweron_knowledge -c 'CREATE EXTENSION IF NOT EXISTS vector;'
|
|
sudo -u postgres psql -d poweron_commcoach -c 'CREATE EXTENSION IF NOT EXISTS vector;'
|
|
EOF
|
|
```
|
|
|
|
### 3. Verifizierung
|
|
|
|
```bash
|
|
ssh -i /tmp/ida-laptop.pem ubuntu@<DB_INTERNAL_IP> \
|
|
"sudo -u postgres psql -d poweron_knowledge -c '\dx vector'"
|
|
```
|
|
|
|
Erwartete Ausgabe: `vector | 0.8.x | public | vector data type and ivfflat and hnsw access methods`
|
|
|
|
**Wichtig:**
|
|
- Der DB-User `poweron_dev` hat keine SUPERUSER-Rechte -- Extension muss als `postgres` User erstellt werden
|
|
- DB-VMs sind nicht direkt per SSH von aussen erreichbar; Zugang via API-Server (`porta-*-platform-core`) im internen Netzwerk
|
|
- Ohne pgvector funktioniert keine RAG-Indexierung (semanticSearch) und kein Content-Index (browseContainer, summarizeContent, searchInFileContent)
|
|
|
|
## Zugriff
|
|
|
|
| Ressource | URL / Pfad |
|
|
|---|---|
|
|
| Infomaniak Cloud Console | `https://www.infomaniak.com/cloud-computing` |
|
|
| OpenStack Horizon | `https://api.pub1.infomaniak.cloud/horizon` |
|
|
| Forgejo (Git + CI/CD) | `https://git.poweron.swiss` |
|
|
| SSH Key (LLM) | `ollama-deploy-key.pem` |
|
|
| SSH Key (Teamsbot) | `teamsbot-deploy-key.pem` (geplant) |
|
|
|
|
Credentials: siehe lokale Datei `local/notes/key.txt` (nicht im Repo).
|