docs: deployment guide from Camellia experience
This commit is contained in:
+155
@@ -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`
|
||||||
Reference in New Issue
Block a user