diff --git a/DEPLOYING.md b/DEPLOYING.md new file mode 100644 index 00000000..d5df6476 --- /dev/null +++ b/DEPLOYING.md @@ -0,0 +1,155 @@ +# 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](https://t.me/BotFather) +- An OpenRouter API key (or other LLM provider) +- systemd (Linux) or launchd (macOS) for service management + +## 2. Install + +```bash +git clone https://github.com/HKUDS/nanobot.git ~/nanobot-src +cd ~/nanobot-src +uv sync +``` + +## 3. Configure + +Run the onboarding wizard: + +```bash +uv run nanobot onboard +``` + +This creates `~/.nanobot/config.json`. Key settings: + +- **model**: `deepseek/deepseek-v4-pro` via 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 + +```bash +uv run nanobot gateway install-service +``` + +This creates `~/.config/systemd/user/nanobot.service` with `Restart=always`. + +Enable lingering so the user service survives logout: + +```bash +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`: + +```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 + +```bash +# 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`: + +```ini +# nanobot-watchdog.service +[Service] +Type=oneshot +ExecStart=/run/wrappers/bin/systemctl --user start nanobot +``` + +```ini +# nanobot-watchdog.timer +[Timer] +OnUnitActiveSec=60s +[Install] +WantedBy=timers.target +``` + +## 9. Rollback safety + +Always deploy from a git checkout so you can revert: + +```bash +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 + +```bash +# 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 sync` +- [ ] `uv run nanobot onboard` +- [ ] Populate workspace (SOUL.md, USER.md, MEMORY.md) +- [ ] `uv run nanobot gateway install-service` +- [ ] `loginctl enable-linger $USER` +- [ ] Firewall, swap, earlyoom +- [ ] Watchdog timer +- [ ] Tag working version: `git tag known-good`