initial commit
This commit is contained in:
@@ -0,0 +1,629 @@
|
||||
# NEXA Deployment Guide
|
||||
|
||||
## 🚀 Architektur-Überblick
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ MEMOS (Port 5230) │
|
||||
│ Interface, Voice-Input, Webhooks │
|
||||
└────────────────────┬────────────────────────────┘
|
||||
│
|
||||
┌───────────┼───────────┐
|
||||
↓ ↓ ↓
|
||||
┌────────┐ ┌────────┐ ┌──────────┐
|
||||
│ n8n │ │ SAIA │ │ Nextcloud│
|
||||
│Logic │ │LiteLLM │ │Tasks/Mail│
|
||||
│7879 │ │4000 │ │80/443 │
|
||||
└────┬───┘ └────┬───┘ └─────┬────┘
|
||||
│ │ │
|
||||
┌────┴───────────┼────────────┴────┐
|
||||
↓ ↓ ↓
|
||||
┌─────────┐ ┌────────────┐ ┌──────────────┐
|
||||
│ QDRANT │ │ GraphDB │ │ Obsidian │
|
||||
│Vector │ │ (Ontotext) │ │(local sync) │
|
||||
│6333 │ │7200 │ │ │
|
||||
└─────────┘ └────────────┘ └──────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📋 Voraussetzungen
|
||||
|
||||
### Hardware
|
||||
- **CPU**: Min. 4 Cores (empfohlen 8)
|
||||
- **RAM**: Min. 16 GB (empfohlen 32 GB)
|
||||
- **Storage**: Min. 100 GB SSD (für Datenbanken & Backups)
|
||||
- **Network**: Stabile Verbindung, HTTPS-ready
|
||||
|
||||
### Software
|
||||
- Docker & Docker Compose (Version 20.10+)
|
||||
- Git
|
||||
- Bash
|
||||
- curl/wget
|
||||
- `.env` Datei aus `.env.example` (mit Secrets gefüllt)
|
||||
|
||||
### Accounts & Credentials
|
||||
- Nextcloud Instanz mit Admin-Zugang
|
||||
- OpenAI API-Key (für SAIA/LiteLLM)
|
||||
- Obsidian Vault Zugang lokalem Filesystem
|
||||
|
||||
---
|
||||
|
||||
## 🐳 Schritt 1: Docker Compose Setup
|
||||
|
||||
### 1.1 Repository klonen
|
||||
|
||||
```bash
|
||||
git clone https://github.com/noheton/nexa.git
|
||||
cd nexa/nexa-core
|
||||
```
|
||||
|
||||
### 1.2 .env konfigurieren
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
# WICHTIG: Alle Secrets eintragen!
|
||||
# - MEMOS_API_KEY
|
||||
# - SAIA_API_KEY
|
||||
# - NC_APP_PASSWORD
|
||||
# - QDRANT_API_KEY
|
||||
# - GRAPHDB_PASSWORD
|
||||
nano .env
|
||||
```
|
||||
|
||||
### 1.3 docker-compose.yml erstellen
|
||||
|
||||
```bash
|
||||
cat > docker-compose.yml << 'EOF'
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
# ===== MEMOS (Interface) =====
|
||||
memos:
|
||||
image: neosmemo/memos:latest
|
||||
container_name: nexa-memos
|
||||
ports:
|
||||
- "5230:5230"
|
||||
volumes:
|
||||
- ./data/memos:/root/.memos
|
||||
environment:
|
||||
MEMOS_PORT: "5230"
|
||||
MEMOS_DRIVER: sqlite
|
||||
MEMOS_DSN: /root/.memos/memos.db
|
||||
networks:
|
||||
- nexa
|
||||
restart: unless-stopped
|
||||
|
||||
# ===== n8n (Workflow Engine) =====
|
||||
n8n:
|
||||
image: n8nio/n8n:latest
|
||||
container_name: nexa-n8n
|
||||
ports:
|
||||
- "5678:5678"
|
||||
volumes:
|
||||
- ./data/n8n:/home/node/.n8n
|
||||
- ./n8n-workflows:/workflows
|
||||
environment:
|
||||
N8N_BASIC_AUTH_ACTIVE: "true"
|
||||
N8N_BASIC_AUTH_USER: "${N8N_USER:-admin}"
|
||||
N8N_BASIC_AUTH_PASSWORD: "${N8N_PASSWORD:-nexa_secure_pass}"
|
||||
N8N_HOST: "${N8N_DOMAIN:-localhost}"
|
||||
N8N_PORT: "5678"
|
||||
N8N_PROTOCOL: https
|
||||
N8N_WEBHOOK_URL: "https://${N8N_DOMAIN:-localhost}/webhook"
|
||||
GENERIC_TIMEZONE: Europe/Berlin
|
||||
DB_TYPE: sqlite
|
||||
DB_SQLITE_PATH: /home/node/.n8n/nexa.db
|
||||
networks:
|
||||
- nexa
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- memos
|
||||
|
||||
# ===== QDRANT (Vector DB) =====
|
||||
qdrant:
|
||||
image: qdrant/qdrant:latest
|
||||
container_name: nexa-qdrant
|
||||
ports:
|
||||
- "6333:6333"
|
||||
volumes:
|
||||
- ./data/qdrant:/qdrant/storage
|
||||
environment:
|
||||
QDRANT_API_KEY: "${QDRANT_API_KEY}"
|
||||
networks:
|
||||
- nexa
|
||||
restart: unless-stopped
|
||||
|
||||
# ===== GraphDB (Ontotext SPARQL) =====
|
||||
graphdb:
|
||||
image: ontotext/graphdb:10-ee
|
||||
container_name: nexa-graphdb
|
||||
ports:
|
||||
- "7200:7200"
|
||||
volumes:
|
||||
- ./data/graphdb:/opt/graphdb/data
|
||||
- ./config/graphdb-init.ttl:/graphdb-import/import.ttl
|
||||
environment:
|
||||
GDB_JAVA_OPTS: "-Xmx8g -Xms4g"
|
||||
GDB_PASSWORD: "${GRAPHDB_PASSWORD}"
|
||||
networks:
|
||||
- nexa
|
||||
restart: unless-stopped
|
||||
|
||||
# ===== SAIA / LiteLLM Proxy (optional - wenn lokal) =====
|
||||
# (Falls SAIA extern gehostet: nicht nötig)
|
||||
|
||||
networks:
|
||||
nexa:
|
||||
driver: bridge
|
||||
|
||||
volumes:
|
||||
nexa_memos:
|
||||
nexa_n8n:
|
||||
nexa_qdrant:
|
||||
nexa_graphdb:
|
||||
EOF
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Schritt 2: Individuelle Service-Konfiguration
|
||||
|
||||
### 2.1 MEMOS Initialisierung
|
||||
|
||||
```bash
|
||||
# Nach memos startup (ca. 30s)
|
||||
curl -X POST http://localhost:5230/api/v1/auth/signup \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"username": "nexa",
|
||||
"password": "secure_password"
|
||||
}'
|
||||
|
||||
# API-Token generieren
|
||||
TOKEN=$(curl -X POST http://localhost:5230/api/v1/auth/signin \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"username":"nexa","password":"secure_password"}' \
|
||||
| jq -r '.data.token')
|
||||
|
||||
echo "MEMOS_API_KEY=$TOKEN" >> .env
|
||||
```
|
||||
|
||||
### 2.2 Qdrant Konfiguration
|
||||
|
||||
```bash
|
||||
# Warte auf Qdrant startup
|
||||
sleep 10
|
||||
|
||||
# Erstelle Collection für Nexa
|
||||
curl -X PUT "http://localhost:6333/collections/nexa_knowledge" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "api-key: ${QDRANT_API_KEY}" \
|
||||
-d '{
|
||||
"vectors": {
|
||||
"size": 1536,
|
||||
"distance": "Cosine"
|
||||
},
|
||||
"optimizers_config": {
|
||||
"deleted_threshold": 0.2,
|
||||
"vacuum_threshold": 0.5,
|
||||
"default_segment_number": 5,
|
||||
"max_segment_number": 30,
|
||||
"memmap_threshold": 268435456,
|
||||
"indexing_threshold": 20000,
|
||||
"flush_interval_sec": 10,
|
||||
"max_optimization_threads": 4
|
||||
}
|
||||
}'
|
||||
|
||||
echo "✅ Qdrant Collection erstellt"
|
||||
```
|
||||
|
||||
### 2.3 GraphDB Initialisierung
|
||||
|
||||
```bash
|
||||
# Warte auf GraphDB startup
|
||||
sleep 15
|
||||
|
||||
# Erstelle Repository
|
||||
GRAPHDB_URL="http://localhost:7200"
|
||||
|
||||
curl -X POST "$GRAPHDB_URL/rest/repositories" \
|
||||
-H "Content-Type: application/json" \
|
||||
-u "admin:${GRAPHDB_PASSWORD}" \
|
||||
-d '{
|
||||
"id": "nexa_knowledge",
|
||||
"title": "Nexa Knowledge Graph",
|
||||
"type": "free",
|
||||
"params": {
|
||||
"baseURL": {
|
||||
"label": "Base URL",
|
||||
"value": "http://nexa.local/"
|
||||
},
|
||||
"defaultLanguage": {
|
||||
"label": "Default language",
|
||||
"value": "en"
|
||||
}
|
||||
}
|
||||
}'
|
||||
|
||||
echo "✅ GraphDB Repository erstellt"
|
||||
```
|
||||
|
||||
### 2.4 n8n Workflows Import
|
||||
|
||||
```bash
|
||||
# Warte auf n8n startup (ca. 60s)
|
||||
sleep 60
|
||||
|
||||
# Importiere Discovery Workflow
|
||||
curl -X POST http://localhost:5678/api/v1/workflows \
|
||||
-H "Content-Type: application/json" \
|
||||
-u "admin:${N8N_PASSWORD}" \
|
||||
-d @n8n-workflows/phase-1/1_1_discovery_workflow.json
|
||||
|
||||
# Importiere Memos Bridge
|
||||
curl -X POST http://localhost:5678/api/v1/workflows \
|
||||
-H "Content-Type: application/json" \
|
||||
-u "admin:${N8N_PASSWORD}" \
|
||||
-d @n8n-workflows/phase-1/1_2_memos_bridge_v2.json
|
||||
|
||||
# Importiere Email Butler
|
||||
curl -X POST http://localhost:5678/api/v1/workflows \
|
||||
-H "Content-Type: application/json" \
|
||||
-u "admin:${N8N_PASSWORD}" \
|
||||
-d @n8n-workflows/phase-2/2_1_email_butler.json
|
||||
|
||||
echo "✅ n8n Workflows importiert"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Schritt 3: Deployment starten
|
||||
|
||||
### 3.1 Docker Compose Up
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
|
||||
# Logs überwachen
|
||||
docker-compose logs -f
|
||||
```
|
||||
|
||||
### 3.2 Health Checks
|
||||
|
||||
```bash
|
||||
# Health Check Script
|
||||
check_service() {
|
||||
local name=$1
|
||||
local url=$2
|
||||
echo "Checking $name..."
|
||||
if curl -s "$url" > /dev/null; then
|
||||
echo "✅ $name: OK"
|
||||
else
|
||||
echo "❌ $name: FAILED"
|
||||
fi
|
||||
}
|
||||
|
||||
sleep 30
|
||||
|
||||
check_service "Memos" "http://localhost:5230"
|
||||
check_service "n8n" "http://localhost:5678"
|
||||
check_service "Qdrant" "http://localhost:6333/health"
|
||||
check_service "GraphDB" "http://localhost:7200/health"
|
||||
|
||||
echo ""
|
||||
echo "🎯 Service URLs:"
|
||||
echo " - Memos: http://localhost:5230"
|
||||
echo " - n8n: http://localhost:5678"
|
||||
echo " - Qdrant: http://localhost:6333"
|
||||
echo " - GraphDB: http://localhost:7200"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Schritt 4: Konfiguration via Command System
|
||||
|
||||
### 4.1 Discovery-Workflow triggern
|
||||
|
||||
```bash
|
||||
# In Memos Memo erstellen:
|
||||
# #nexa:config
|
||||
|
||||
# Oder via API:
|
||||
curl -X POST http://localhost:5678/api/v1/workflows/run \
|
||||
-H "Content-Type: application/json" \
|
||||
-u "admin:${N8N_PASSWORD}" \
|
||||
-d '{
|
||||
"workflowId": "discovery-workflow-id"
|
||||
}'
|
||||
```
|
||||
|
||||
### 4.2 Automatische Konfiguration laden
|
||||
|
||||
Nach erfolgreichem Discovery werden Nextcloud-Listen-IDs:
|
||||
|
||||
```bash
|
||||
# Es wird automatisch aktualisiert in:
|
||||
# - Qdrant: als Metadata
|
||||
# - n8n: als Umgebungsvariablen
|
||||
# - Memos: als Confirmation-Memo
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔐 Schritt 5: Reverse Proxy Setup (Production)
|
||||
|
||||
### 5.1 Nginx Configuration
|
||||
|
||||
```bash
|
||||
cat > /etc/nginx/sites-available/nexa.conf << 'EOF'
|
||||
upstream memos_backend {
|
||||
server localhost:5230;
|
||||
}
|
||||
|
||||
upstream n8n_backend {
|
||||
server localhost:5678;
|
||||
}
|
||||
|
||||
upstream qdrant_backend {
|
||||
server localhost:6333;
|
||||
}
|
||||
|
||||
upstream graphdb_backend {
|
||||
server localhost:7200;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name nexa.yourdomain.com;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/nexa.yourdomain.com/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/nexa.yourdomain.com/privkey.pem;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||
|
||||
# MEMOS
|
||||
location / {
|
||||
proxy_pass http://memos_backend;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_read_timeout 3600s;
|
||||
proxy_send_timeout 3600s;
|
||||
}
|
||||
|
||||
# n8n
|
||||
location /n8n/ {
|
||||
proxy_pass http://n8n_backend/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
}
|
||||
|
||||
# Qdrant (nur intern, wenn nötig)
|
||||
location /qdrant/ {
|
||||
allow 10.0.0.0/8;
|
||||
deny all;
|
||||
proxy_pass http://qdrant_backend/;
|
||||
}
|
||||
|
||||
# GraphDB (nur intern)
|
||||
location /graphdb/ {
|
||||
allow 10.0.0.0/8;
|
||||
deny all;
|
||||
proxy_pass http://graphdb_backend/;
|
||||
}
|
||||
|
||||
# Webhook endpoint für externe Services
|
||||
location /webhook/ {
|
||||
proxy_pass http://n8n_backend/webhook/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name nexa.yourdomain.com;
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
EOF
|
||||
|
||||
# Aktivieren
|
||||
sudo ln -s /etc/nginx/sites-available/nexa.conf /etc/nginx/sites-enabled/
|
||||
sudo nginx -t
|
||||
sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Schritt 6: Monitoring & Backups
|
||||
|
||||
### 6.1 Backup Script
|
||||
|
||||
```bash
|
||||
cat > scripts/backup_nexa.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
|
||||
BACKUP_DIR="./backups/$(date +%Y%m%d_%H%M%S)"
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
echo "🔄 Backing up Nexa..."
|
||||
|
||||
# Backup Datenbanken
|
||||
docker-compose exec -T qdrant tar czf - /qdrant/storage > "$BACKUP_DIR/qdrant.tar.gz"
|
||||
docker-compose exec -T graphdb tar czf - /opt/graphdb/data > "$BACKUP_DIR/graphdb.tar.gz"
|
||||
docker-compose exec -T memos tar czf - /root/.memos > "$BACKUP_DIR/memos.tar.gz"
|
||||
docker-compose exec -T n8n tar czf - /home/node/.n8n > "$BACKUP_DIR/n8n.tar.gz"
|
||||
|
||||
# Backup Configs
|
||||
cp .env "$BACKUP_DIR/.env.backup"
|
||||
cp docker-compose.yml "$BACKUP_DIR/docker-compose.yml.backup"
|
||||
|
||||
echo "✅ Backup completed: $BACKUP_DIR"
|
||||
|
||||
# Optional: zu S3 hochladen
|
||||
# aws s3 sync "$BACKUP_DIR" s3://nexa-backups/$(date +%Y%m%d)/
|
||||
EOF
|
||||
|
||||
chmod +x scripts/backup_nexa.sh
|
||||
|
||||
# Tägliches Backup (cron)
|
||||
echo "0 2 * * * /path/to/nexa/scripts/backup_nexa.sh" | crontab -
|
||||
```
|
||||
|
||||
### 6.2 Health Check Monitoring
|
||||
|
||||
```bash
|
||||
cat > scripts/monitor_nexa.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
|
||||
# Monitore Service Status
|
||||
SERVICES=("memos" "n8n" "qdrant" "graphdb")
|
||||
|
||||
for service in "${SERVICES[@]}"; do
|
||||
if docker-compose ps $service | grep -q "Up"; then
|
||||
echo "✅ $service: Running"
|
||||
else
|
||||
echo "❌ $service: DOWN"
|
||||
# Restart bei Fehler
|
||||
docker-compose restart $service
|
||||
fi
|
||||
done
|
||||
EOF
|
||||
|
||||
chmod +x scripts/monitor_nexa.sh
|
||||
|
||||
# Alle 5 Minuten
|
||||
echo "*/5 * * * * /path/to/nexa/scripts/monitor_nexa.sh" | crontab -
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Schritt 7: Validation & Testing
|
||||
|
||||
### 7.1 End-to-End Test
|
||||
|
||||
```bash
|
||||
cat > scripts/test_nexa.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
|
||||
echo "🧪 Testing Nexa Installation..."
|
||||
|
||||
# Test 1: Memos API
|
||||
echo "Test 1: Memos API"
|
||||
if curl -s http://localhost:5230/api/v1/auth/status | jq . > /dev/null 2>&1; then
|
||||
echo "✅ Memos: OK"
|
||||
else
|
||||
echo "❌ Memos: FAILED"
|
||||
fi
|
||||
|
||||
# Test 2: n8n API
|
||||
echo "Test 2: n8n API"
|
||||
if curl -s -u "admin:${N8N_PASSWORD}" http://localhost:5678/api/v1/workflows | jq . > /dev/null 2>&1; then
|
||||
echo "✅ n8n: OK"
|
||||
else
|
||||
echo "❌ n8n: FAILED"
|
||||
fi
|
||||
|
||||
# Test 3: Qdrant Collection
|
||||
echo "Test 3: Qdrant Collection"
|
||||
if curl -s -H "api-key: ${QDRANT_API_KEY}" http://localhost:6333/collections/nexa_knowledge | jq . > /dev/null 2>&1; then
|
||||
echo "✅ Qdrant: OK"
|
||||
else
|
||||
echo "❌ Qdrant: FAILED"
|
||||
fi
|
||||
|
||||
# Test 4: GraphDB Repository
|
||||
echo "Test 4: GraphDB Repository"
|
||||
if curl -s -u "admin:${GRAPHDB_PASSWORD}" http://localhost:7200/repositories | jq . > /dev/null 2>&1; then
|
||||
echo "✅ GraphDB: OK"
|
||||
else
|
||||
echo "❌ GraphDB: FAILED"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "🎯 Create Test Memo:"
|
||||
MEMO=$(curl -s -X POST http://localhost:5230/api/v1/memos \
|
||||
-H "Authorization: Bearer ${MEMOS_API_KEY}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"content": "Test memo - #nexa:config"}' | jq -r '.id')
|
||||
|
||||
echo "✅ Test Memo created: $MEMO"
|
||||
echo "Check Memos UI to verify webhook triggers Discovery"
|
||||
EOF
|
||||
|
||||
chmod +x scripts/test_nexa.sh
|
||||
./scripts/test_nexa.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🆘 Troubleshooting
|
||||
|
||||
### Problem: Memos kann sich nicht mit n8n verbinden
|
||||
|
||||
```bash
|
||||
# Überprüfe n8n Webhook URL in Memos config
|
||||
curl http://localhost:5678/webhook/memos
|
||||
|
||||
# Falls 404: Workflow ist nicht aktiviert/deployed
|
||||
docker-compose logs n8n | grep webhook
|
||||
```
|
||||
|
||||
### Problem: GraphDB startet nicht
|
||||
|
||||
```bash
|
||||
# Memory-Limit erhöhen
|
||||
docker-compose exec graphdb -e "GDB_JAVA_OPTS=-Xmx16g -Xms8g" restart
|
||||
|
||||
# Logs checken
|
||||
docker-compose logs graphdb
|
||||
```
|
||||
|
||||
### Problem: Qdrant Collection leer
|
||||
|
||||
```bash
|
||||
# Überprüfe ob Memos Bridge Workflow läuft
|
||||
docker-compose logs n8n | grep "memos_bridge"
|
||||
|
||||
# Manuell test
|
||||
curl -X POST http://localhost:5230/api/v1/memos \
|
||||
-H "Authorization: Bearer ${MEMOS_API_KEY}" \
|
||||
-d '{"content": "- [ ] Test task #nexa"}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📈 Next Steps
|
||||
|
||||
1. ✅ **Phase 1 deployt**: Memos Bridge & Discovery laufen
|
||||
2. ⏳ **Phase 2 aktivieren**: Email Butler (wenn Nextcloud Mail konfiguriert)
|
||||
3. ⏳ **Phase 3 setup**: Qdrant Embedding Pipeline
|
||||
4. ⏳ **Phase 4 integration**: GraphRAG Queries testen
|
||||
5. ⏳ **Phase 5**: Home Assistant Voice Integration
|
||||
|
||||
---
|
||||
|
||||
## 📞 Support & Debugging
|
||||
|
||||
```bash
|
||||
# Alle Logs in eine Datei sammeln
|
||||
docker-compose logs > deployment_logs.txt
|
||||
|
||||
# Spezifischer Service
|
||||
docker-compose logs n8n --tail 100
|
||||
|
||||
# Wiederherstellung aus Backup
|
||||
./scripts/restore_nexa.sh backup/2024-01-15_120000/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Deployment abgeschlossen! Nexa ist nun betriebsbereit.** 🚀
|
||||
Reference in New Issue
Block a user