Skip to main content

Overview

nanobot supports running multiple instances simultaneously, each with its own:
  • Configuration file (config.json)
  • Workspace directory (memory, sessions, cron jobs)
  • Gateway port
  • Channel connections
  • Model and provider settings
This is useful for:
  • Connecting to multiple chat platforms with different configs
  • Running separate bots for different teams or projects
  • Testing configurations without affecting production
  • Isolating workspaces for security or organizational purposes

Command-Line Options

Each nanobot command accepts these flags:
OptionShortDefaultDescription
--workspace-w~/.nanobot/workspaceWorkspace directory (MEMORY.md, sessions, cron)
--config-c~/.nanobot/config.jsonConfiguration file path
--port-p18790Gateway port

Basic Usage

Example: Telegram and Discord Bots

1

Create separate directories

mkdir -p ~/.nanobot/telegram
mkdir -p ~/.nanobot/discord
2

Initialize configurations

Initialize each instance:
# Telegram instance
nanobot onboard -w ~/.nanobot/telegram

# Discord instance  
nanobot onboard -w ~/.nanobot/discord
Each creates its own config.json and workspace.
3

Configure channels

Edit ~/.nanobot/telegram/config.json:
{
  "providers": {
    "openrouter": {
      "apiKey": "sk-or-v1-xxx"
    }
  },
  "agents": {
    "defaults": {
      "model": "anthropic/claude-opus-4-5"
    }
  },
  "channels": {
    "telegram": {
      "enabled": true,
      "token": "TELEGRAM_BOT_TOKEN",
      "allowFrom": ["your_telegram_user_id"]
    }
  }
}
Edit ~/.nanobot/discord/config.json:
{
  "providers": {
    "openrouter": {
      "apiKey": "sk-or-v1-xxx"
    }
  },
  "agents": {
    "defaults": {
      "model": "anthropic/claude-opus-4-5"
    }
  },
  "channels": {
    "discord": {
      "enabled": true,
      "token": "DISCORD_BOT_TOKEN",
      "allowFrom": ["your_discord_user_id"]
    }
  }
}
4

Run both gateways

In separate terminal windows:
# Terminal 1: Telegram bot
nanobot gateway -w ~/.nanobot/telegram -p 18791

# Terminal 2: Discord bot
nanobot gateway -w ~/.nanobot/discord -p 18792
Each instance must use a different port to avoid conflicts. The default is 18790.

Instance Isolation

Each instance is completely isolated:

Workspace Separation

~/.nanobot/
├── telegram/
   ├── config.json
   ├── workspace/
   ├── MEMORY.md           # Telegram bot's memory
   ├── HEARTBEAT.md        # Telegram bot's periodic tasks
   ├── cron/
   └── jobs.json       # Telegram bot's cron jobs
   └── sessions/           # Telegram conversation sessions
   └── .whatsapp-session/      # (if using WhatsApp)
├── discord/
   ├── config.json
   ├── workspace/
   ├── MEMORY.md           # Discord bot's memory
   ├── HEARTBEAT.md        # Discord bot's periodic tasks
   ├── cron/
   └── jobs.json       # Discord bot's cron jobs
   └── sessions/           # Discord conversation sessions
   └── matrix-store/           # (if using Matrix)
└── workspace/                   # Default instance

Configuration Independence

Each instance can have:
  • Different LLM providers (OpenRouter, Anthropic, OpenAI, etc.)
  • Different models (GPT-4, Claude, Gemini, etc.)
  • Different enabled channels
  • Different security settings (workspace restrictions, allow lists)
  • Different tools (MCP servers, skills)

Port Assignment

Assign unique ports to each instance:
# Instance A: Telegram
nanobot gateway -w ~/.nanobot/telegram -p 18791

# Instance B: Discord
nanobot gateway -w ~/.nanobot/discord -p 18792

# Instance C: Feishu
nanobot gateway -w ~/.nanobot/feishu -p 18793

Deployment Methods

Manual (Terminal Windows)

Run each instance in a separate terminal:
# Terminal 1
nanobot gateway -w ~/.nanobot/botA -p 18791

# Terminal 2
nanobot gateway -w ~/.nanobot/botB -p 18792
This method is only suitable for development. Use systemd or Docker for production.

Using tmux/screen

Run instances in persistent terminal sessions:
# Create tmux sessions
tmux new -s nanobot-telegram -d "nanobot gateway -w ~/.nanobot/telegram -p 18791"
tmux new -s nanobot-discord -d "nanobot gateway -w ~/.nanobot/discord -p 18792"

# List sessions
tmux ls

# Attach to a session
tmux attach -t nanobot-telegram

# Kill sessions
tmux kill-session -t nanobot-telegram

Using systemd (Linux)

Create separate service files for each instance: ~/.config/systemd/user/nanobot-telegram.service:
[Unit]
Description=Nanobot Gateway (Telegram)
After=network.target

[Service]
Type=simple
ExecStart=%h/.local/bin/nanobot gateway -w %h/.nanobot/telegram -p 18791
Restart=always
RestartSec=10
NoNewPrivileges=yes
ProtectSystem=strict
ReadWritePaths=%h/.nanobot/telegram

[Install]
WantedBy=default.target
~/.config/systemd/user/nanobot-discord.service:
[Unit]
Description=Nanobot Gateway (Discord)
After=network.target

[Service]
Type=simple
ExecStart=%h/.local/bin/nanobot gateway -w %h/.nanobot/discord -p 18792
Restart=always
RestartSec=10
NoNewPrivileges=yes
ProtectSystem=strict
ReadWritePaths=%h/.nanobot/discord

[Install]
WantedBy=default.target
Enable and start:
systemctl --user daemon-reload
systemctl --user enable --now nanobot-telegram nanobot-discord

# Check status
systemctl --user status nanobot-telegram
systemctl --user status nanobot-discord

# Enable lingering for 24/7 operation
loginctl enable-linger $USER
See Linux Service for more details.

Using Docker Compose

docker-compose.yml:
version: '3.8'

services:
  nanobot-telegram:
    build: .
    container_name: nanobot-telegram
    command: ["gateway", "-w", "/root/.nanobot", "-p", "18791"]
    restart: unless-stopped
    volumes:
      - ~/.nanobot/telegram:/root/.nanobot
    ports:
      - 18791:18791
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M

  nanobot-discord:
    build: .
    container_name: nanobot-discord
    command: ["gateway", "-w", "/root/.nanobot", "-p", "18792"]
    restart: unless-stopped
    volumes:
      - ~/.nanobot/discord:/root/.nanobot
    ports:
      - 18792:18792
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M

  nanobot-feishu:
    build: .
    container_name: nanobot-feishu
    command: ["gateway", "-w", "/root/.nanobot", "-p", "18793"]
    restart: unless-stopped
    volumes:
      - ~/.nanobot/feishu:/root/.nanobot
    ports:
      - 18793:18793
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
Start all instances:
docker compose up -d

# View logs
docker compose logs -f nanobot-telegram
docker compose logs -f nanobot-discord

# Stop all
docker compose down
See Docker Deployment for more details.

Advanced Configurations

Different Models per Instance

Production bot (uses Claude Opus):
telegram/config.json
{
  "agents": {
    "defaults": {
      "model": "anthropic/claude-opus-4-5",
      "provider": "openrouter"
    }
  }
}
Testing bot (uses cheaper model):
discord/config.json
{
  "agents": {
    "defaults": {
      "model": "anthropic/claude-3.5-sonnet",
      "provider": "openrouter"
    }
  }
}

Different Providers per Instance

Instance A (uses OpenRouter):
{
  "providers": {
    "openrouter": {
      "apiKey": "sk-or-v1-xxx"
    }
  },
  "agents": {
    "defaults": {
      "model": "anthropic/claude-opus-4-5",
      "provider": "openrouter"
    }
  }
}
Instance B (uses Anthropic directly):
{
  "providers": {
    "anthropic": {
      "apiKey": "sk-ant-xxx"
    }
  },
  "agents": {
    "defaults": {
      "model": "claude-opus-4-5",
      "provider": "anthropic"
    }
  }
}

Security Isolation

Production instance (restricted workspace):
production/config.json
{
  "tools": {
    "restrictToWorkspace": true,
    "exec": {
      "pathAppend": ""
    }
  },
  "channels": {
    "telegram": {
      "enabled": true,
      "allowFrom": ["admin_user_id"]
    }
  }
}
Development instance (unrestricted):
development/config.json
{
  "tools": {
    "restrictToWorkspace": false
  },
  "channels": {
    "telegram": {
      "enabled": true,
      "allowFrom": ["dev_user_id"]
    }
  }
}

Different MCP Servers per Instance

Data analysis bot (has database access):
data-bot/config.json
{
  "tools": {
    "mcpServers": {
      "postgres": {
        "command": "npx",
        "args": ["-y", "@modelcontextprotocol/server-postgres", "postgresql://..."]
      }
    }
  }
}
File management bot (has filesystem access):
file-bot/config.json
{
  "tools": {
    "mcpServers": {
      "filesystem": {
        "command": "npx",
        "args": ["-y", "@modelcontextprotocol/server-filesystem", "/data"]
      }
    }
  }
}

CLI Operations per Instance

Run CLI commands against specific instances:
# Check status of specific instance
nanobot status -w ~/.nanobot/telegram

# Chat with specific instance
nanobot agent -w ~/.nanobot/telegram -m "Hello"

# Interactive chat with specific instance
nanobot agent -w ~/.nanobot/discord

# Check channel status
nanobot channels status -w ~/.nanobot/telegram

Monitoring Multiple Instances

Check All Instance Statuses

#!/bin/bash
# check-instances.sh

for instance in telegram discord feishu; do
  echo "=== $instance ==="
  nanobot status -w ~/.nanobot/$instance
  echo
done

Monitor Logs (systemd)

# Follow all instance logs
journalctl --user -u nanobot-telegram -u nanobot-discord -u nanobot-feishu -f

# Check if all instances are running
systemctl --user status nanobot-telegram nanobot-discord nanobot-feishu

Monitor Containers (Docker)

# View all instance statuses
docker compose ps

# Follow all logs
docker compose logs -f

# Check resource usage
docker stats

Load Balancing

For high-traffic deployments, run multiple instances behind a load balancer:
docker-compose.yml
services:
  nanobot-1:
    build: .
    command: ["gateway", "-p", "18790"]
    volumes:
      - nanobot-shared-config:/root/.nanobot
    networks:
      - nanobot-net

  nanobot-2:
    build: .
    command: ["gateway", "-p", "18790"]
    volumes:
      - nanobot-shared-config:/root/.nanobot
    networks:
      - nanobot-net

  nginx:
    image: nginx:alpine
    ports:
      - 18790:18790
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - nanobot-1
      - nanobot-2
    networks:
      - nanobot-net

volumes:
  nanobot-shared-config:

networks:
  nanobot-net:
Load balancing requires careful session management. Ensure session affinity (sticky sessions) is configured in your load balancer.

Troubleshooting

Port Conflicts

Error: Address already in use Solution: Check which instance is using the port:
ss -tlnp | grep 18790
Either stop the conflicting instance or use a different port.

Config File Not Found

Error: Config file not found: ~/.nanobot/config.json Solution: Specify the correct config path:
nanobot gateway -w ~/.nanobot/telegram -c ~/.nanobot/telegram/config.json
Or ensure the config exists in the workspace directory:
ls -la ~/.nanobot/telegram/config.json

Workspace Conflicts

Error: Sessions from different instances interfering Solution: Always use separate workspace directories:
# Bad: Both instances share default workspace
nanobot gateway -p 18791  # Uses ~/.nanobot/workspace
nanobot gateway -p 18792  # Uses ~/.nanobot/workspace (conflict!)

# Good: Separate workspaces
nanobot gateway -w ~/.nanobot/telegram -p 18791
nanobot gateway -w ~/.nanobot/discord -p 18792

Instance Won’t Start

Check logs: systemd:
journalctl --user -u nanobot-telegram -n 50
Docker:
docker compose logs nanobot-telegram
Common issues:
  • Port already in use (use different port)
  • Missing config file (run nanobot onboard -w <workspace>)
  • Invalid JSON in config (validate with jq)
  • Missing API keys

High Memory Usage with Multiple Instances

Set resource limits: systemd:
[Service]
MemoryMax=512M
CPUQuota=50%
Docker Compose:
deploy:
  resources:
    limits:
      cpus: '0.5'
      memory: 512M

Best Practices

Use Cases

Team Collaboration

Run separate instances for different teams:
  • Marketing team: Telegram bot with content creation skills
  • Engineering team: Discord bot with code execution and GitHub integration
  • Support team: Email bot with knowledge base access

Environment Separation

  • Production: Stable model, workspace restrictions, allow list
  • Staging: Latest model, moderate restrictions, QA team access
  • Development: Experimental features, no restrictions, developer access

Channel Specialization

  • Public bot: Restrictive config, rate limiting, limited tools
  • Private bot: Full access, all tools, trusted users only

Geographic Distribution

  • US instance: Uses US-based providers, US timezone
  • EU instance: Uses EU-based providers, GDPR compliance, EU timezone
  • APAC instance: Uses APAC providers, APAC timezone

Next Steps

Docker Deployment

Container-based deployment for multiple instances

Linux Service

systemd service configuration for multiple instances

Channel Setup

Configure different channels per instance

Configuration

Complete configuration reference

Build docs developers (and LLMs) love