176 lines
6.3 KiB
Markdown
176 lines
6.3 KiB
Markdown
---
|
||
name: live-mongodb
|
||
description: Connect to the live (production) MongoDB via chisel tunnel and perform read/write operations. Use this skill when you need to inspect or update live data directly in the production database.
|
||
---
|
||
|
||
# Live MongoDB Access via Chisel Tunnel
|
||
|
||
## Overview
|
||
|
||
Die Produktions-MongoDB läuft auf dem Server aus `PRODUCTION_SERVER` in `.env`. Der Zugang erfolgt über einen **Chisel-Tunnel**, der den Remote-MongoDB-Port auf localhost mapped. Damit kann man dann entweder über `mongosh`, `mongodump`/`mongorestore`, oder den **MongoDB MCP Server** auf die Live-Daten zugreifen.
|
||
|
||
## Umgebungsvariablen (aus .env)
|
||
|
||
| Variable | Beschreibung |
|
||
| ------------------------ | ----------------------------------------------- |
|
||
| `PRODUCTION_SERVER` | Produktionsserver (z.B. `dock4.basehosts.de`) |
|
||
| `PRODUCTION_TIBI_PREFIX` | DB-Prefix auf Produktion (z.B. `wmbasic`) |
|
||
| `TIBI_NAMESPACE` | Projekt-Namespace |
|
||
| **Live DB Name** | = `${PRODUCTION_TIBI_PREFIX}_${TIBI_NAMESPACE}` |
|
||
| Chisel-Port (Remote) | `10987` — Chisel-Server auf dem Produktionshost |
|
||
|
||
## Schritt 1: Chisel-Tunnel starten
|
||
|
||
Das Chisel-Passwort muss vom User bereitgestellt werden. Tunnel starten:
|
||
|
||
```bash
|
||
# Passwort vom User erfragen oder aus Umgebung nehmen
|
||
read -s -p "Chisel-Passwort: " CHISEL_PASSWORD
|
||
|
||
# Tunnel starten (mappt remote mongo:27017 → localhost:27017)
|
||
chisel client --auth "coder:${CHISEL_PASSWORD}" \
|
||
http://${PRODUCTION_SERVER}:10987 \
|
||
27017:mongo:27017 &
|
||
|
||
# Kurz warten, bis der Tunnel steht
|
||
sleep 3
|
||
```
|
||
|
||
**WICHTIG:** Der lokale Docker-Mongo-Container muss gestoppt sein oder auf einem anderen Port laufen, da der Tunnel Port 27017 lokal belegt. Falls der lokale Container läuft:
|
||
|
||
```bash
|
||
# Lokales MongoDB stoppen (belegt sonst Port 27017)
|
||
docker compose -f docker-compose-local.yml stop mongo
|
||
```
|
||
|
||
Alternativ kann der Tunnel auf einen anderen lokalen Port gemappt werden:
|
||
|
||
```bash
|
||
chisel client --auth "coder:${CHISEL_PASSWORD}" \
|
||
http://${PRODUCTION_SERVER}:10987 \
|
||
37017:mongo:27017 &
|
||
# → erreichbar unter mongodb://localhost:37017/${PRODUCTION_TIBI_PREFIX}_${TIBI_NAMESPACE}
|
||
```
|
||
|
||
## Schritt 2: Verbinden
|
||
|
||
### Option A: mongosh (interaktiv)
|
||
|
||
```bash
|
||
mongosh "mongodb://localhost:27017/${PRODUCTION_TIBI_PREFIX}_${TIBI_NAMESPACE}"
|
||
```
|
||
|
||
### Option B: MongoDB MCP Server (für Copilot)
|
||
|
||
Den MongoDB MCP über die Umgebungsvariable `MDB_MCP_CONNECTION_STRING` auf die Live-DB umleiten.
|
||
|
||
**Temporär für eine Session** – in `.vscode/mcp.json` eine zweite Server-Config eintragen:
|
||
|
||
```jsonc
|
||
{
|
||
"servers": {
|
||
"mongodb-live": {
|
||
"command": "npx",
|
||
"args": ["-y", "mongodb-mcp-server@latest"],
|
||
"type": "stdio",
|
||
"env": {
|
||
"MDB_MCP_CONNECTION_STRING": "mongodb://localhost:27017/${PRODUCTION_TIBI_PREFIX}_${TIBI_NAMESPACE}",
|
||
"MDB_MCP_READ_ONLY": "false",
|
||
"MDB_MCP_TELEMETRY": "disabled",
|
||
},
|
||
},
|
||
},
|
||
}
|
||
```
|
||
|
||
> **Achtung:** `MDB_MCP_READ_ONLY=false` erlaubt Schreiboperationen! Nach getaner Arbeit den Server wieder entfernen oder auf `true` setzen.
|
||
|
||
### Option C: Einmalige Kommandos via Terminal
|
||
|
||
```bash
|
||
DB_NAME="${PRODUCTION_TIBI_PREFIX}_${TIBI_NAMESPACE}"
|
||
|
||
# Dokument suchen
|
||
mongosh "mongodb://localhost:27017/$DB_NAME" \
|
||
--eval 'db.content.findOne({path: "/"})'
|
||
|
||
# Feld updaten
|
||
mongosh "mongodb://localhost:27017/$DB_NAME" \
|
||
--eval 'db.content.updateOne({path: "/"}, {$set: {"title": "Neuer Titel"}})'
|
||
```
|
||
|
||
## Schritt 3: Tunnel beenden
|
||
|
||
```bash
|
||
killall chisel
|
||
```
|
||
|
||
Falls der lokale Mongo-Container vorher gestoppt wurde, wieder starten:
|
||
|
||
```bash
|
||
docker compose -f docker-compose-local.yml start mongo
|
||
```
|
||
|
||
## Sicherheitsregeln
|
||
|
||
1. **Immer zuerst lesen, dann schreiben.** Vor jedem Update das betroffene Dokument mit `find`/`findOne` inspizieren.
|
||
2. **Backup vor Bulk-Updates.** Bei Massenänderungen vorher ein `mongodump` machen:
|
||
```bash
|
||
mongodump --uri="mongodb://localhost:27017" \
|
||
--db=${PRODUCTION_TIBI_PREFIX}_${TIBI_NAMESPACE} \
|
||
--collection=<collection> \
|
||
--gzip --archive=backup-<collection>-$(date +%Y%m%d-%H%M%S).gz
|
||
```
|
||
3. **User muss Chisel-Passwort liefern.** Das Passwort niemals hardcoden oder in Dateien speichern.
|
||
4. **Updates immer bestätigen lassen.** Vor jeder Schreiboperation dem User die geplante Query zeigen und explizit nach Bestätigung fragen.
|
||
5. **Nach getaner Arbeit Tunnel schließen** und ggf. `mongodb-live` MCP-Server aus der Config entfernen.
|
||
6. **Kein Drop/Delete von Collections** ohne explizite User-Anweisung.
|
||
7. **SSR-Cache leeren nach Datenänderungen.** Wenn Daten in Collections geändert werden, die auf der Website gerendert werden (z.B. `content`, `navigation`), muss der SSR-Cache invalidiert werden, damit die Änderungen sichtbar werden. Dazu die `ssr`-Collection leeren:
|
||
```bash
|
||
mongosh "mongodb://localhost:27017/$DB_NAME" \
|
||
--eval 'db.ssr.deleteMany({})'
|
||
```
|
||
Siehe auch den Skill `tibi-ssr-caching` für Details zur Cache-Invalidierung über die API.
|
||
|
||
## Wichtige Collections
|
||
|
||
| Collection | Beschreibung |
|
||
| ------------ | ------------------------------- |
|
||
| `content` | CMS-Inhaltsseiten (Pagebuilder) |
|
||
| `navigation` | Navigationsstruktur |
|
||
| `medialib` | Medien-Bibliothek |
|
||
| `ssr` | SSR-Cache |
|
||
|
||
> Weitere Collections je nach Projekt — siehe `api/collections/` für die aktuelle Liste.
|
||
|
||
## Typische Anwendungsfälle
|
||
|
||
### Content-Eintrag inspizieren
|
||
|
||
```js
|
||
db.content.findOne({ path: "/" })
|
||
```
|
||
|
||
### Navigation aktualisieren
|
||
|
||
```js
|
||
db.navigation.updateOne({ type: "header", language: "de" }, { $set: { "items.0.label": "Neues Label" } })
|
||
```
|
||
|
||
### Dokument-Struktur inspizieren
|
||
|
||
```js
|
||
// Schema einer Collection anschauen
|
||
db.content.findOne()
|
||
|
||
// Alle Felder eines Dokuments auflisten
|
||
Object.keys(db.content.findOne())
|
||
```
|
||
|
||
## Fehlerbehebung
|
||
|
||
- **"Connection refused" auf Port 27017:** Chisel-Tunnel läuft nicht oder lokaler Mongo blockiert den Port. Prüfen mit `ss -tlnp | grep 27017`.
|
||
- **"Authentication failed":** Chisel-Passwort falsch. User erneut fragen.
|
||
- **Langsame Queries:** Produktions-DB kann große Collections haben. Immer mit Filtern arbeiten, nie `find({})` ohne Limit.
|
||
- **Rate Limiting:** Kein Thema bei direktem DB-Zugang (nur bei API-Calls relevant).
|