# π’ Deployment Guide
## Robotics MCP WebApp
This guide covers deployment, configuration, and operational procedures for the Robotics MCP WebApp.
---
## π Table of Contents
- [Prerequisites](#prerequisites)
- [Local Development](#local-development)
- [Docker Deployment](#docker-deployment)
- [Kubernetes Deployment](#kubernetes-deployment)
- [Cloud Deployment](#cloud-deployment)
- [Configuration](#configuration)
- [Monitoring](#monitoring)
- [Backup & Recovery](#backup--recovery)
- [Troubleshooting](#troubleshooting)
---
## π Prerequisites
### System Requirements
#### Minimum Requirements
- **CPU**: 2 cores (4 cores recommended)
- **RAM**: 4GB (8GB recommended)
- **Storage**: 20GB available space
- **Network**: Stable internet connection (10Mbps+)
#### Recommended Production Setup
- **CPU**: 4+ cores
- **RAM**: 8GB+
- **Storage**: 50GB+ SSD
- **Network**: 100Mbps+ connection
### Software Dependencies
#### Required Software
```bash
# Ubuntu/Debian
sudo apt update
sudo apt install -y curl wget git docker.io docker-compose
# macOS
brew install docker docker-compose git
# Windows
# Install Docker Desktop, Git Bash, and WSL2
```
#### Development Tools
```bash
# Node.js 18+
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs
# Python 3.10+
sudo apt install -y python3.10 python3.10-venv python3-pip
# Git
sudo apt install -y git
```
### Network Configuration
#### Firewall Settings
```bash
# Allow HTTP/HTTPS
sudo ufw allow 80
sudo ufw allow 443
# Allow SSH (change default port for security)
sudo ufw allow 22
# Allow WebSocket connections
sudo ufw allow 8354 # Backend API
sudo ufw allow 3000 # Frontend (development)
```
#### Domain Configuration
```bash
# Add domain to /etc/hosts for testing
echo "127.0.0.1 robotics-webapp.local" | sudo tee -a /etc/hosts
```
---
## π οΈ Local Development
### Environment Setup
1. **Clone Repository**
```bash
git clone https://github.com/sandraschi/robotics-webapp.git
cd robotics-webapp
```
2. **Create Environment Files**
```bash
# Frontend environment
cp frontend/.env.example frontend/.env.local
# Backend environment
cp backend/.env.example backend/.env
```
3. **Configure Environment Variables**
```bash
# frontend/.env.local
NEXT_PUBLIC_API_URL=http://localhost:8354
NEXT_PUBLIC_WS_URL=ws://localhost:8354/ws/robotics
# backend/.env
DATABASE_URL=postgresql://user:password@localhost:5432/robotics
SECRET_KEY=your-secret-key-here
ALLOWED_ORIGINS=http://localhost:3000
```
4. **Start Services**
```bash
# Terminal 1: Frontend
cd frontend
npm install
npm run dev
# Terminal 2: Backend
cd backend
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
python main.py
# Terminal 3: Database (if using local PostgreSQL)
sudo service postgresql start
```
5. **Verify Installation**
```bash
# Check frontend
curl http://localhost:3000
# Check backend
curl http://localhost:8354/health
# Check WebSocket
# Open browser dev tools and connect to ws://localhost:8354/ws/robotics
```
### Development Workflow
#### Code Changes
```bash
# Create feature branch
git checkout -b feature/new-feature
# Make changes
# Run tests
npm test
pytest
# Commit changes
git add .
git commit -m "feat: add new feature"
# Push and create PR
git push origin feature/new-feature
```
#### Testing
```bash
# Frontend tests
cd frontend
npm run test:unit
npm run test:e2e
# Backend tests
cd backend
python -m pytest tests/
# Integration tests
docker-compose -f docker-compose.test.yml up --abort-on-container-exit
```
---
## π³ Docker Deployment
### Docker Compose (Recommended)
1. **Create Docker Compose File**
```yaml
# docker-compose.yml
version: '3.8'
services:
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
ports:
- "3000:3000"
environment:
- NEXT_PUBLIC_API_URL=http://backend:8354
depends_on:
- backend
backend:
build:
context: ./backend
dockerfile: Dockerfile
ports:
- "8354:8354"
environment:
- DATABASE_URL=postgresql://user:password@db:5432/robotics
- SECRET_KEY=your-secret-key
depends_on:
- db
db:
image: postgres:15
environment:
- POSTGRES_DB=robotics
- POSTGRES_USER=user
- POSTGRES_PASSWORD=password
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
```
2. **Build and Deploy**
```bash
# Build images
docker-compose build
# Start services
docker-compose up -d
# Check logs
docker-compose logs -f
# Check health
curl http://localhost:3000
curl http://localhost:8354/health
```
### Production Docker Setup
#### Multi-stage Dockerfile (Frontend)
```dockerfile
# frontend/Dockerfile
FROM node:18-alpine AS base
# Install dependencies
FROM base AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --only=production
# Build application
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
# Production image
FROM base AS runner
WORKDIR /app
ENV NODE_ENV production
ENV NEXT_TELEMETRY_DISABLED 1
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT 3000
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/api/health || exit 1
CMD ["node", "server.js"]
```
#### Multi-stage Dockerfile (Backend)
```dockerfile
# backend/Dockerfile
FROM python:3.11-slim
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV PYTHONPATH /app
# Install system dependencies
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
gcc \
libc6-dev \
curl \
&& rm -rf /var/lib/apt/lists/*
# Create app user
RUN groupadd -r appuser && useradd -r -g appuser appuser
WORKDIR /app
# Install Python dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy application code
COPY --chown=appuser:appuser . .
# Switch to non-root user
USER appuser
EXPOSE 8354
HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \
CMD python -c "import requests; requests.get('http://localhost:8354/health')"
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8354", "--workers", "4"]
```
### Docker Production Commands
```bash
# Build production images
docker build -t robotics-webapp/frontend:latest ./frontend
docker build -t robotics-webapp/backend:latest ./backend
# Run production containers
docker run -d \
--name robotics-backend \
-p 8354:8354 \
-e DATABASE_URL="postgresql://..." \
-e SECRET_KEY="your-secret" \
robotics-webapp/backend:latest
docker run -d \
--name robotics-frontend \
-p 3000:3000 \
-e NEXT_PUBLIC_API_URL="http://your-domain.com:8354" \
robotics-webapp/frontend:latest
# Check container health
docker ps
docker logs robotics-backend
docker logs robotics-frontend
```
---
## βΈοΈ Kubernetes Deployment
### Prerequisites
```bash
# Install kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
# Install Helm
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# Configure kubectl
aws eks update-kubeconfig --region your-region --name your-cluster
```
### Namespace Setup
```yaml
# k8s/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: robotics
labels:
name: robotics
```
### ConfigMaps and Secrets
```yaml
# k8s/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: robotics-config
namespace: robotics
data:
DATABASE_HOST: "robotics-db-postgresql.robotics.svc.cluster.local"
REDIS_HOST: "robotics-redis-master.robotics.svc.cluster.local"
ALLOWED_ORIGINS: "https://robotics-webapp.com"
---
# k8s/secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: robotics-secret
namespace: robotics
type: Opaque
data:
# Base64 encoded values
DATABASE_PASSWORD: <base64-encoded-password>
SECRET_KEY: <base64-encoded-secret>
API_KEY: <base64-encoded-api-key>
```
### Database Deployment
```yaml
# k8s/postgresql.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: robotics-db
namespace: robotics
spec:
replicas: 1
selector:
matchLabels:
app: robotics-db
template:
metadata:
labels:
app: robotics-db
spec:
containers:
- name: postgresql
image: postgres:15
ports:
- containerPort: 5432
env:
- name: POSTGRES_DB
value: "robotics"
- name: POSTGRES_USER
value: "robotics"
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: robotics-secret
key: DATABASE_PASSWORD
volumeMounts:
- name: postgres-storage
mountPath: /var/lib/postgresql/data
volumes:
- name: postgres-storage
persistentVolumeClaim:
claimName: robotics-db-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: robotics-db-pvc
namespace: robotics
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Gi
```
### Backend Deployment
```yaml
# k8s/backend.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: robotics-backend
namespace: robotics
spec:
replicas: 3
selector:
matchLabels:
app: robotics-backend
template:
metadata:
labels:
app: robotics-backend
spec:
containers:
- name: backend
image: robotics-webapp/backend:latest
ports:
- containerPort: 8354
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: robotics-secret
key: DATABASE_URL
- name: SECRET_KEY
valueFrom:
secretKeyRef:
name: robotics-secret
key: SECRET_KEY
resources:
requests:
memory: "256Mi"
cpu: "200m"
limits:
memory: "1Gi"
cpu: "1000m"
livenessProbe:
httpGet:
path: /health
port: 8354
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: 8354
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: robotics-backend
namespace: robotics
spec:
selector:
app: robotics-backend
ports:
- port: 8354
targetPort: 8354
type: ClusterIP
```
### Frontend Deployment
```yaml
# k8s/frontend.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: robotics-frontend
namespace: robotics
spec:
replicas: 2
selector:
matchLabels:
app: robotics-frontend
template:
metadata:
labels:
app: robotics-frontend
spec:
containers:
- name: frontend
image: robotics-webapp/frontend:latest
ports:
- containerPort: 3000
env:
- name: NEXT_PUBLIC_API_URL
value: "http://robotics-backend.robotics.svc.cluster.local:8354"
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /api/health
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /api/health
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: robotics-frontend
namespace: robotics
spec:
selector:
app: robotics-frontend
ports:
- port: 3000
targetPort: 3000
type: ClusterIP
```
### Ingress Configuration
```yaml
# k8s/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: robotics-ingress
namespace: robotics
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/rate-limit: "100"
nginx.ingress.kubernetes.io/rate-limit-window: "1m"
spec:
ingressClassName: nginx
tls:
- hosts:
- robotics-webapp.com
- api.robotics-webapp.com
secretName: robotics-tls
rules:
- host: robotics-webapp.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: robotics-frontend
port:
number: 3000
- host: api.robotics-webapp.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: robotics-backend
port:
number: 8000
```
### Deploy to Kubernetes
```bash
# Create namespace
kubectl apply -f k8s/namespace.yaml
# Deploy secrets and configmaps
kubectl apply -f k8s/configmap.yaml
kubectl apply -f k8s/secret.yaml
# Deploy database
kubectl apply -f k8s/postgresql.yaml
# Wait for database to be ready
kubectl wait --for=condition=available --timeout=300s deployment/robotics-db -n robotics
# Deploy backend
kubectl apply -f k8s/backend.yaml
# Wait for backend to be ready
kubectl wait --for=condition=available --timeout=300s deployment/robotics-backend -n robotics
# Deploy frontend
kubectl apply -f k8s/frontend.yaml
# Deploy ingress
kubectl apply -f k8s/ingress.yaml
# Check deployment status
kubectl get pods -n robotics
kubectl get services -n robotics
kubectl get ingress -n robotics
```
---
## βοΈ Cloud Deployment
### AWS Deployment
#### EC2 + RDS Setup
1. **Launch EC2 Instance**
```bash
# Ubuntu 22.04 LTS, t3.medium or larger
aws ec2 run-instances \
--image-id ami-0abcdef1234567890 \
--instance-type t3.medium \
--key-name your-key-pair \
--security-groups robotics-sg
```
2. **Setup RDS PostgreSQL**
```bash
aws rds create-db-instance \
--db-instance-identifier robotics-db \
--db-instance-class db.t3.micro \
--engine postgres \
--master-username robotics \
--master-user-password your-password \
--allocated-storage 20
```
3. **Deploy Application**
```bash
# SSH into EC2 instance
ssh -i your-key.pem ubuntu@your-instance-ip
# Install Docker and deploy
sudo apt update
sudo apt install -y docker.io docker-compose
# Clone and deploy
git clone https://github.com/sandraschi/robotics-webapp.git
cd robotics-webapp
docker-compose -f docker-compose.prod.yml up -d
```
#### ECS + Fargate Deployment
```yaml
# ecs-task-definition.json
{
"family": "robotics-webapp",
"taskRoleArn": "arn:aws:iam::123456789012:role/ecsTaskRole",
"executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "256",
"memory": "512",
"containerDefinitions": [
{
"name": "frontend",
"image": "123456789012.dkr.ecr.us-east-1.amazonaws.com/robotics-frontend:latest",
"portMappings": [
{
"containerPort": 3000,
"protocol": "tcp"
}
],
"environment": [
{
"name": "NEXT_PUBLIC_API_URL",
"value": "http://backend.local:8354"
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/robotics-frontend",
"awslogs-region": "us-east-1",
"awslogs-stream-prefix": "ecs"
}
}
},
{
"name": "backend",
"image": "123456789012.dkr.ecr.us-east-1.amazonaws.com/robotics-backend:latest",
"portMappings": [
{
"containerPort": 8354,
"protocol": "tcp"
}
],
"environment": [
{
"name": "DATABASE_URL",
"value": "postgresql://..."
},
{
"name": "SECRET_KEY",
"value": "your-secret-key"
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/robotics-backend",
"awslogs-region": "us-east-1",
"awslogs-stream-prefix": "ecs"
}
}
}
]
}
```
### Vercel + Railway Deployment
#### Frontend (Vercel)
```bash
# Install Vercel CLI
npm i -g vercel
# Deploy frontend
cd frontend
vercel --prod
# Set environment variables
vercel env add NEXT_PUBLIC_API_URL
```
#### Backend (Railway)
```bash
# Install Railway CLI
npm install -g @railway/cli
# Login and deploy
railway login
railway deploy
# Set environment variables
railway variables set DATABASE_URL=postgresql://...
railway variables set SECRET_KEY=your-secret-key
```
---
## βοΈ Configuration
### Environment Variables
#### Frontend Configuration
```bash
# .env.local
NEXT_PUBLIC_API_URL=http://localhost:8354
NEXT_PUBLIC_WS_URL=ws://localhost:8354/ws/robotics
NEXT_PUBLIC_ENVIRONMENT=development
NEXT_PUBLIC_VERSION=1.0.0
NEXT_PUBLIC_SENTRY_DSN=your-sentry-dsn
```
#### Backend Configuration
```bash
# .env
DATABASE_URL=postgresql://user:password@localhost:5432/robotics
SECRET_KEY=your-secret-key-here
ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=30
# CORS settings
ALLOWED_ORIGINS=http://localhost:3000,https://robotics-webapp.com
ALLOW_CREDENTIALS=true
# WebSocket settings
WS_MAX_CONNECTIONS=1000
WS_MESSAGE_TIMEOUT=30
# Redis (optional)
REDIS_URL=redis://localhost:6379
# External APIs
OPENAI_API_KEY=your-openai-key
WORLDLABS_API_KEY=your-worldlabs-key
```
### Application Configuration
#### Database Configuration
```python
# backend/config.py
from pydantic import BaseSettings
class Settings(BaseSettings):
database_url: str = "postgresql://user:password@localhost/robotics"
secret_key: str = "your-secret-key"
algorithm: str = "HS256"
access_token_expire_minutes: int = 30
# CORS
allowed_origins: list = ["http://localhost:3000"]
allow_credentials: bool = True
# WebSocket
ws_max_connections: int = 1000
ws_message_timeout: int = 30
# Redis
redis_url: str = "redis://localhost:6379"
class Config:
env_file = ".env"
settings = Settings()
```
#### Feature Flags
```python
# Feature flag configuration
FEATURE_FLAGS = {
"world_labs_integration": True,
"vr_platform_support": True,
"advanced_analytics": False,
"multi_robot_support": True,
"real_time_collaboration": False,
}
```
---
## π Monitoring
### Application Monitoring
#### Prometheus Metrics
```python
# backend/monitoring.py
from prometheus_client import Counter, Histogram, Gauge, generate_latest
from fastapi import Response
REQUEST_COUNT = Counter('http_requests_total', 'Total HTTP requests', ['method', 'endpoint', 'status'])
REQUEST_LATENCY = Histogram('http_request_duration_seconds', 'HTTP request latency', ['method', 'endpoint'])
ACTIVE_CONNECTIONS = Gauge('websocket_active_connections', 'Number of active WebSocket connections')
ROBOT_COUNT = Gauge('robots_total', 'Total number of robots', ['status'])
@app.get("/metrics")
async def metrics():
"""Prometheus metrics endpoint"""
return Response(generate_latest(), media_type="text/plain")
```
#### Health Checks
```python
# backend/health.py
from fastapi import APIRouter
import time
router = APIRouter()
@app.get("/health")
async def health_check():
"""Basic health check"""
return {
"status": "healthy",
"timestamp": time.time(),
"version": "1.0.0"
}
@app.get("/health/detailed")
async def detailed_health_check():
"""Detailed health check with dependencies"""
health_status = {
"status": "healthy",
"timestamp": time.time(),
"version": "1.0.0",
"checks": {}
}
# Check database
try:
await database.health_check()
health_status["checks"]["database"] = "healthy"
except Exception as e:
health_status["checks"]["database"] = f"unhealthy: {e}"
health_status["status"] = "unhealthy"
# Check WebSocket connections
active_connections = len(websocket_manager.active_connections)
health_status["checks"]["websocket"] = f"{active_connections} active connections"
# Check external services
try:
await check_world_labs_api()
health_status["checks"]["world_labs"] = "healthy"
except Exception as e:
health_status["checks"]["world_labs"] = f"unhealthy: {e}"
return health_status
```
### Infrastructure Monitoring
#### Grafana Dashboard Setup
```yaml
# grafana/provisioning/dashboards/robotics-dashboard.yaml
apiVersion: 1
providers:
- name: 'robotics'
type: file
disableDeletion: false
updateIntervalSeconds: 10
allowUiUpdates: true
options:
path: /var/lib/grafana/dashboards
```
#### Alert Manager Configuration
```yaml
# alertmanager/config.yml
global:
smtp_smarthost: 'smtp.gmail.com:587'
smtp_from: 'alerts@robotics-webapp.com'
route:
group_by: ['alertname']
group_wait: 10s
group_interval: 10s
repeat_interval: 1h
receiver: 'email'
receivers:
- name: 'email'
email_configs:
- to: 'admin@robotics-webapp.com'
subject: 'Robotics Alert: {{ .GroupLabels.alertname }}'
rule_files:
- "alert_rules.yml"
```
---
## πΎ Backup & Recovery
### Database Backup
#### Automated PostgreSQL Backup
```bash
# backup.sh
#!/bin/bash
BACKUP_DIR="/opt/robotics/backups"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/robotics_$TIMESTAMP.sql"
# Create backup directory
mkdir -p $BACKUP_DIR
# Perform backup
pg_dump -h localhost -U robotics -d robotics > $BACKUP_FILE
# Compress backup
gzip $BACKUP_FILE
# Clean old backups (keep last 30 days)
find $BACKUP_DIR -name "*.sql.gz" -mtime +30 -delete
echo "Backup completed: $BACKUP_FILE.gz"
```
#### Cron Job Setup
```bash
# Add to crontab for daily backups at 2 AM
0 2 * * * /opt/robotics/backup.sh
# Verify cron job
crontab -l
```
### Application Data Backup
#### Configuration Backup
```bash
# config-backup.sh
#!/bin/bash
BACKUP_DIR="/opt/robotics/config-backups"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
# Backup environment files
tar -czf $BACKUP_DIR/env_$TIMESTAMP.tar.gz \
/opt/robotics/frontend/.env.local \
/opt/robotics/backend/.env
# Backup Docker volumes
docker run --rm -v robotics_postgres_data:/data \
-v $BACKUP_DIR:/backup \
alpine tar czf /backup/postgres_$TIMESTAMP.tar.gz -C / data
echo "Configuration backup completed"
```
### Recovery Procedures
#### Database Recovery
```bash
# Stop application
docker-compose down
# Restore database
gunzip robotics_backup.sql.gz
psql -h localhost -U robotics -d robotics < robotics_backup.sql
# Restart application
docker-compose up -d
```
#### Application Recovery
```bash
# Pull latest code
git pull origin main
# Rebuild containers
docker-compose build --no-cache
# Deploy
docker-compose up -d
# Verify health
curl http://localhost:8354/health
curl http://localhost:3000
```
---
## π§ Troubleshooting
### Common Issues
#### WebSocket Connection Issues
```bash
# Check WebSocket endpoint
curl -I http://localhost:8354/ws/robotics
# Check firewall settings
sudo ufw status
# Check Docker network
docker network ls
docker network inspect robotics_default
```
#### Database Connection Issues
```bash
# Test database connection
psql -h localhost -U robotics -d robotics -c "SELECT 1;"
# Check database logs
docker logs robotics_db
# Verify environment variables
docker exec robotics_backend env | grep DATABASE
```
#### Performance Issues
```bash
# Check system resources
top
htop
df -h
# Check application logs
docker logs robotics_backend --tail 100
docker logs robotics_frontend --tail 100
# Check WebSocket connections
netstat -tlnp | grep :8354
```
### Debug Commands
#### Application Debug
```bash
# Enable debug logging
export LOG_LEVEL=DEBUG
docker-compose up
# Check application metrics
curl http://localhost:8354/metrics
# Test WebSocket connection
wscat -c ws://localhost:8354/ws/robotics
```
#### Database Debug
```bash
# Check active connections
psql -h localhost -U robotics -d robotics -c "SELECT count(*) FROM pg_stat_activity;"
# Check slow queries
psql -h localhost -U robotics -d robotics -c "SELECT * FROM pg_stat_statements ORDER BY total_time DESC LIMIT 10;"
# Analyze table statistics
psql -h localhost -U robotics -d robotics -c "ANALYZE;"
```
### Log Analysis
#### Log Aggregation
```bash
# View all logs
docker-compose logs -f
# Filter logs by service
docker-compose logs -f backend
# Search logs for errors
docker-compose logs | grep ERROR
# Export logs for analysis
docker-compose logs > logs_$(date +%Y%m%d_%H%M%S).txt
```
#### Log Rotation
```bash
# Configure log rotation
cat > /etc/logrotate.d/robotics << EOF
/opt/robotics/logs/*.log {
daily
rotate 30
compress
delaycompress
missingok
create 644 robotics robotics
postrotate
docker-compose restart
endscript
}
EOF
```
### Emergency Procedures
#### Service Restart
```bash
# Restart all services
docker-compose restart
# Restart specific service
docker-compose restart backend
# Force rebuild and restart
docker-compose up --build --force-recreate
```
#### Data Recovery
```bash
# Restore from backup
gunzip latest_backup.sql.gz
psql -h localhost -U robotics -d robotics < latest_backup.sql
# Verify data integrity
psql -h localhost -U robotics -d robotics -c "SELECT count(*) FROM robots;"
```
---
## π Support
### Getting Help
1. **Check Documentation**: Review this deployment guide and troubleshooting section
2. **Search Issues**: Check [GitHub Issues](https://github.com/sandraschi/robotics-webapp/issues) for similar problems
3. **Community Support**: Join our [Discord server](https://discord.gg/robotics-webapp) for community help
4. **Professional Support**: Contact [robotics@sandraschi.dev](mailto:robotics@sandraschi.dev) for priority support
### Escalation Process
- **Level 1**: Documentation and community support
- **Level 2**: GitHub issues with detailed reproduction steps
- **Level 3**: Direct email support with logs and system information
- **Level 4**: Emergency support for production outages
### System Information Collection
When reporting issues, please include:
```bash
# System information
uname -a
docker --version
docker-compose --version
# Application status
docker ps
docker stats
# Logs
docker-compose logs --tail 100
# Configuration (redacted)
env | grep -E "(DATABASE|SECRET|API)" | sed 's/=.*$/=***REDACTED***/'
```
This deployment guide provides comprehensive instructions for setting up and maintaining the Robotics MCP WebApp in various environments. Follow the appropriate section based on your deployment requirements and infrastructure preferences.