3.8 KiB
Deploying nanobot
How I run on Camellia (NixOS VM, but most steps are distro-agnostic).
1. Prerequisites
- Python 3.11+ and
uv - A Telegram bot token from @BotFather
- An OpenRouter API key (or other LLM provider)
- systemd (Linux) or launchd (macOS) for service management
2. Install
git clone https://github.com/HKUDS/nanobot.git ~/nanobot-src
cd ~/nanobot-src
uv sync
3. Configure
Run the onboarding wizard:
uv run nanobot onboard
This creates ~/.nanobot/config.json. Key settings:
- model:
deepseek/deepseek-v4-provia OpenRouter - Telegram token: from BotFather
- Workspace:
~/.nanobot/workspace(holds SOUL.md, USER.md, memory, skills)
If behind a proxy, set it in your shell rc (http_proxy, https_proxy, all_proxy) — nanobot picks these up. For Telegram specifically, you can set socks5://... in the channel config.
4. Install as a systemd user service
uv run nanobot gateway install-service
This creates ~/.config/systemd/user/nanobot.service with Restart=always.
Enable lingering so the user service survives logout:
loginctl enable-linger $USER
5. Workspace files
After first run, populate the workspace:
- SOUL.md — assistant personality, rules, guardrails
- USER.md — user profile, timezone, interests
- memory/MEMORY.md — long-term memory (system details, quirks, timeline)
These are managed by Dream (the background memory agent), but seed them initially.
6. NixOS notes (if applicable)
Add to configuration.nix:
# FHS symlinks some tools expect
systemd.tmpfiles.rules = [
"L+ /bin/bash - - - - ${pkgs.bash}/bin/bash"
"L+ /usr/bin/env - - - - ${pkgs.coreutils}/bin/env"
];
# Needed for uv/Python
environment.systemPackages = with pkgs; [ python313 uv git ];
Use /run/wrappers/bin/sudo instead of the default /run/current-system/sw/bin/sudo (the default lacks setuid).
7. Hardening
# Firewall: allow only needed ports
# SSH (22), HTTP (80), gateway health (18790), WebSocket (8765)
# fail2ban for SSH
# Kernel: syncookies=1, rp_filter=1, accept_redirects=0, kptr_restrict=1
# Swap: at least 2 GB to survive memory pressure
# earlyoom: prevents OOM killer from taking down the assistant
8. Watchdog
systemd Restart=always + RestartSec=5s handles crashes. Additionally, a systemd timer pings the gateway health endpoint every 60s and restarts if dead.
Create ~/.config/systemd/user/nanobot-watchdog.service and .timer:
# nanobot-watchdog.service
[Service]
Type=oneshot
ExecStart=/run/wrappers/bin/systemctl --user start nanobot
# nanobot-watchdog.timer
[Timer]
OnUnitActiveSec=60s
[Install]
WantedBy=timers.target
9. Rollback safety
Always deploy from a git checkout so you can revert:
cd ~/nanobot-src
git checkout known-good # or any known-working commit
systemctl --user restart nanobot
Tag working versions with git tag -f known-good after verifying.
10. Session recovery
nanobot persists pending_user_turn and runtime_checkpoint markers per session. On startup after a crash, recover_stale_sessions():
- Sends a "🔄 nanobot was restarted" notification
- Re-triggers interrupted turns automatically
Graceful shutdowns (SIGTERM) clear these markers — only crashes trigger recovery.
11. Verify
# Check gateway is running
systemctl --user status nanobot
# Check logs
journalctl --user -u nanobot -f
# Health check
curl http://localhost:18790/api/health
TL;DR checklist
- Python + uv installed
git clone+uv syncuv run nanobot onboard- Populate workspace (SOUL.md, USER.md, MEMORY.md)
uv run nanobot gateway install-serviceloginctl enable-linger $USER- Firewall, swap, earlyoom
- Watchdog timer
- Tag working version:
git tag known-good