Skip to main content

Production Deployment

Deploy MachinaOs to a production server with Docker, nginx reverse proxy, and SSL.

Server Requirements

  • Ubuntu 20.04+ or similar Linux
  • 2+ CPU cores
  • 2GB+ RAM
  • Docker and Docker Compose
  • Domain name (for SSL)

Deployment Overview

Internet --> nginx (SSL) --> Docker Containers
                   |
                   +--> frontend (3000)
                   +--> backend (3010)
                   +--> whatsapp (9400)
                   +--> redis (6379)

Step 1: Server Setup

# Update system
sudo apt update && sudo apt upgrade -y

# Install Docker
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER

# Install Docker Compose
sudo apt install docker-compose-plugin

# Install nginx
sudo apt install nginx certbot python3-certbot-nginx

Step 2: Clone and Configure

# Clone repository
cd /opt
sudo git clone https://github.com/trohitg/MachinaOs.git
cd MachinaOs

# Create production environment file
sudo cp .env.example .env.prod
sudo nano .env.prod

Production Environment

# .env.prod
VITE_CLIENT_PORT=3000
PYTHON_BACKEND_PORT=3010
WHATSAPP_RPC_PORT=9400

# Security - CHANGE THESE
SECRET_KEY=your-random-64-char-string
JWT_SECRET_KEY=your-random-32-char-string
API_KEY_ENCRYPTION_KEY=your-random-64-char-string

# Authentication
AUTH_MODE=single
JWT_COOKIE_SECURE=true
JWT_COOKIE_SAMESITE=strict

# Cache
REDIS_ENABLED=true
REDIS_URL=redis://redis:6379

# CORS - your domain
CORS_ORIGINS=["https://your-domain.com"]

# Logging
LOG_LEVEL=INFO
DEBUG=false
Generate secure random strings for SECRET_KEY, JWT_SECRET_KEY, and API_KEY_ENCRYPTION_KEY. Never use default values in production.

Step 3: Build and Start

# Build production images
docker-compose -f docker-compose.prod.yml build

# Start services
docker-compose -f docker-compose.prod.yml up -d

# Verify containers
docker-compose -f docker-compose.prod.yml ps

Step 4: Configure nginx

Create nginx configuration:
sudo nano /etc/nginx/sites-available/machinaos
server {
    listen 80;
    server_name your-domain.com;

    location / {
        return 301 https://$server_name$request_uri;
    }
}

server {
    listen 443 ssl http2;
    server_name your-domain.com;

    # SSL configuration (will be added by certbot)

    # Frontend
    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        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;
    }

    # Backend API
    location /api/ {
        proxy_pass http://127.0.0.1:3010/api/;
        proxy_http_version 1.1;
        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;
    }

    # WebSocket
    location /ws/ {
        proxy_pass http://127.0.0.1:3010/ws/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_read_timeout 86400;
    }

    # Webhooks
    location /webhook/ {
        proxy_pass http://127.0.0.1:3010/webhook/;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    # Health check
    location /health {
        proxy_pass http://127.0.0.1:3010/health;
    }
}
Enable the site:
sudo ln -s /etc/nginx/sites-available/machinaos /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Step 5: SSL Certificate

# Get SSL certificate from Let's Encrypt
sudo certbot --nginx -d your-domain.com

# Auto-renewal is configured automatically
# Test renewal
sudo certbot renew --dry-run

Step 6: Firewall

# Allow required ports
sudo ufw allow 22/tcp   # SSH
sudo ufw allow 80/tcp   # HTTP (redirect)
sudo ufw allow 443/tcp  # HTTPS
sudo ufw enable

Verify Deployment

# Check health endpoint
curl https://your-domain.com/health

# Check containers
docker-compose -f docker-compose.prod.yml ps

# View logs
docker-compose -f docker-compose.prod.yml logs -f

Maintenance

Updates

cd /opt/MachinaOs

# Pull latest code
git pull

# Rebuild and restart
docker-compose -f docker-compose.prod.yml down
docker-compose -f docker-compose.prod.yml up --build -d

Backups

# Backup database
docker cp machinaos-backend-1:/app/data/workflow.db ./backup/

# Backup WhatsApp session
docker cp machinaos-whatsapp-1:/app/data ./backup/whatsapp/

Monitoring

# Check resource usage
docker stats --no-stream

# Check logs for errors
docker-compose -f docker-compose.prod.yml logs --tail=100 backend

Log Rotation

Add to /etc/logrotate.d/docker:
/var/lib/docker/containers/*/*.log {
    rotate 7
    daily
    compress
    missingok
    delaycompress
    copytruncate
}

Security Checklist

All secret keys are randomly generated and unique
SSL/TLS is enabled with valid certificate
JWT_COOKIE_SECURE is set to true
CORS_ORIGINS only includes your domain
DEBUG is set to false
Firewall is configured
SSH key authentication (disable password auth)

Troubleshooting

  • Check if containers are running: docker-compose ps
  • Verify ports match nginx config
  • Check backend logs: docker-compose logs backend
  • Verify nginx WebSocket config has Upgrade headers
  • Check proxy_read_timeout is set
  • Ensure firewall allows connections
# Renew certificate manually
sudo certbot renew --force-renewal
sudo systemctl reload nginx
  • Check for memory leaks: docker stats
  • Restart containers: docker-compose restart
  • Increase server RAM if needed

Scaling

For higher load:
  1. Horizontal scaling: Use Docker Swarm or Kubernetes
  2. Database: Migrate from SQLite to PostgreSQL
  3. Cache: Use Redis cluster
  4. Load balancer: Add HAProxy or cloud load balancer