Skip to content

Single Node Deployment

Deploy Machineuse on a single server for development or small-scale production.

Overview

Single node mode combines the control plane and worker functionality:

┌────────────────────────────────────────┐
│            Single Node                 │
│  ┌──────────────────────────────────┐  │
│  │          API Server              │  │
│  │  ┌─────────┐  ┌───────────────┐  │  │
│  │  │Scheduler│  │ Storage(SQLite)│  │  │
│  │  └─────────┘  └───────────────┘  │  │
│  └──────────────────────────────────┘  │
│  ┌──────────────────────────────────┐  │
│  │      Container Runtime           │  │
│  │  ┌────────┐ ┌────────┐ ┌────────┐│  │
│  │  │  Inst  │ │  Inst  │ │  Inst  ││  │
│  │  └────────┘ └────────┘ └────────┘│  │
│  └──────────────────────────────────┘  │
└────────────────────────────────────────┘

Requirements

  • Ubuntu 20.04+ or Debian 11+
  • Python 3.11+
  • systemd-nspawn support
  • 4+ GB RAM
  • 20+ GB disk space
  • Root/sudo access

Installation

Using Docker

git clone https://github.com/dotcommoners/machineuse.git
cd machineuse
docker-compose up -d

Manual Installation

# Clone repository
git clone https://github.com/dotcommoners/machineuse.git
cd machineuse

# Install dependencies
cd machineuse-api
poetry install

# Run deployment script
sudo ./scripts/install.sh --mode single_node

Configuration

Create /etc/machineuse/config.json:

{
  "deployment_mode": "single_node",
  "node_id": "single-node-1",
  "api": {
    "host": "0.0.0.0",
    "port": 8000
  },
  "storage": {
    "backend": "sqlite",
    "database_path": "/var/lib/machineuse/machineuse.db"
  },
  "containers": {
    "max_instances": 20,
    "default_memory_mb": 2048,
    "default_cpu_cores": 2
  }
}

Or generate using CLI:

machineuse-cli config init single_node -o /etc/machineuse/config.json

Starting the Service

Using systemd

sudo systemctl enable machineuse
sudo systemctl start machineuse

Using the startup script

./scripts/start-single-node.sh

Manually

cd machineuse-api
poetry run python -m uvicorn machineuse.api.server:app --host 0.0.0.0 --port 8000

Verification

# Check service status
sudo systemctl status machineuse

# Test API
curl http://localhost:8000/health

# Test CLI
machineuse-cli health

# Create test instance
machineuse-cli create --image ubuntu:22.04

Resource Tuning

Memory Allocation

For a 16GB server:

{
  "containers": {
    "max_instances": 6,
    "default_memory_mb": 2048
  }
}

Rule of thumb: Leave 2-4GB for the OS and Machineuse overhead.

CPU Allocation

{
  "containers": {
    "default_cpu_cores": 2,
    "limits": {
      "max_cpu_cores": 4
    }
  }
}

Disk Space

Ensure sufficient space for: - Container base images (~2GB each) - Running containers (~1-5GB each) - Snapshots (varies with usage)

# Check disk usage
df -h /var/lib/machineuse

SSL/TLS Setup

Using Let's Encrypt

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

# Obtain certificate
sudo certbot --nginx -d yourdomain.com

# Auto-renewal
sudo systemctl enable certbot.timer

Nginx Configuration

server {
    listen 443 ssl;
    server_name yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Backup and Recovery

Database Backup

# SQLite backup
cp /var/lib/machineuse/machineuse.db /backup/machineuse-$(date +%Y%m%d).db

Snapshot Backup

# Backup all snapshots
tar -czf /backup/snapshots-$(date +%Y%m%d).tar.gz /var/lib/machineuse/snapshots/

Automated Backup Script

#!/bin/bash
BACKUP_DIR=/backup/machineuse
DATE=$(date +%Y%m%d-%H%M%S)

# Backup database
cp /var/lib/machineuse/machineuse.db $BACKUP_DIR/db-$DATE.db

# Backup configuration
cp /etc/machineuse/config.json $BACKUP_DIR/config-$DATE.json

# Cleanup old backups (keep 7 days)
find $BACKUP_DIR -mtime +7 -delete

Troubleshooting

Service Won't Start

# Check logs
journalctl -u machineuse -f

# Verify configuration
machineuse-cli config validate /etc/machineuse/config.json

Container Creation Fails

# Check systemd-nspawn
sudo systemd-nspawn --version

# Check base image
ls -la /var/lib/machines/

# Check disk space
df -h

High Memory Usage

# List running instances
machineuse-cli list

# Check instance memory
machineuse-cli metrics

# Make idle instances dormant
machineuse-cli bulk dormant --status idle

Scaling Up

When you outgrow single-node:

  1. Deploy a control plane
  2. Convert this node to a worker
  3. Add additional workers

See Distributed Deployment for details.