docs: NixOS deployment guide from Camellia

This commit is contained in:
nanobot
2026-07-31 15:36:51 +08:00
parent 617a0129b7
commit 66b8743024
+194
View File
@@ -0,0 +1,194 @@
# Deploying nanobot on NixOS
This documents what it took to get nanobot running on Camellia (NixOS 26.05).
See `/etc/nixos/configuration.nix` for the full config — every block below has a matching section there.
## 1. Base system
```nix
# Hostname, timezone, SSH, fail2ban
networking.hostName = "Camellia";
time.timeZone = "Asia/Shanghai";
services.openssh = { enable = true; ... };
services.fail2ban = { enable = true; };
```
## 2. Required packages
```nix
environment.systemPackages = with pkgs; [
git curl wget vim tmux htop jq fd ripgrep
python313 uv # nanobot runtime
nodejs_22 # for some skills/tools
];
```
## 3. Users
Create a dedicated user for nanobot with lingering enabled:
```nix
users.users.claw = {
extraGroups = ["sudo"];
isNormalUser = true;
linger = true; # user services survive logout
};
security.sudo.extraRules = [
{ users = ["claw"]; commands = [{ command = "ALL"; options = ["NOPASSWD"]; }]; }
];
```
## 4. FHS symlinks
nanobot's `exec` tool (and many scripts) expect `/bin/bash`:
```nix
systemd.tmpfiles.rules = [
"L+ /bin/bash - - - - /run/current-system/sw/bin/bash"
"L+ /usr/bin/env - - - - /run/current-system/sw/bin/env"
];
```
## 5. nanobot systemd user service
```nix
systemd.user.services.nanobot = {
description = "nanobot AI assistant gateway";
wantedBy = ["default.target"];
serviceConfig = {
Type = "simple";
ExecStart = "/home/claw/nanobot-src/.venv/bin/python -m nanobot gateway --foreground --port 18790";
Restart = "always";
RestartSec = 5;
WorkingDirectory = "/home/claw/.nanobot/workspace";
Environment = "HOME=/home/claw";
};
};
```
Use a git checkout (`/home/claw/nanobot-src`) so you can `git checkout known-good` to rollback.
## 6. Watchdog timer
Covers the case where systemd misses a crash:
```nix
systemd.user.services.nanobot-watchdog = {
serviceConfig = {
Type = "oneshot";
ExecStart = "${pkgs.systemd}/bin/systemctl --user start nanobot";
};
};
systemd.user.timers.nanobot-watchdog = {
timerConfig = { OnUnitActiveSec = "60s"; };
};
```
## 7. Reverse proxy (Caddy)
nanobot's gateway binds to `127.0.0.1` by default and rejects non-local connections. For a dedicated VM this is over-cautious, so we use Caddy to reverse-proxy the WebSocket UI externally:
```nix
services.caddy = {
enable = true;
virtualHosts."http://192.168.122.194".extraConfig = ''
reverse_proxy 127.0.0.1:8765
'';
};
```
## 8. Proxy for outbound traffic (v2rayA)
If the LLM API and Telegram are blocked:
```nix
services.v2raya = { enable = true; };
```
Then configure proxy env vars in `~/.bashrc`:
```bash
export http_proxy=http://127.0.0.1:20171
export https_proxy=http://127.0.0.1:20171
export all_proxy=socks5://127.0.0.1:20170
```
## 9. OOM protection
nanobot can spike memory. Without this, the kernel OOM killer takes it down:
```nix
services.earlyoom = {
enable = true;
freeMemThreshold = 5;
freeSwapThreshold = 10;
};
swapDevices = [{ device = "/swapfile"; size = 2048; }]; # 2 GB
```
## 10. Firewall
```nix
networking.firewall.allowedTCPPorts = [
22 # SSH
80 # Caddy HTTP
2017 # v2rayA web UI
20170 # v2rayA SOCKS5
20171 # v2rayA HTTP proxy
];
```
## 11. Kernel hardening
```nix
boot.kernel.sysctl = {
"net.ipv4.tcp_syncookies" = 1;
"net.ipv4.conf.all.rp_filter" = 1;
"net.ipv4.conf.all.accept_redirects" = 0;
"net.ipv6.conf.all.accept_redirects" = 0;
"kernel.kptr_restrict" = 1;
"kernel.dmesg_restrict" = 1;
};
```
## 12. Nix GC
```nix
nix.gc = { automatic = true; dates = "weekly"; options = "--delete-older-than 30d"; };
```
## 13. Mirrors (for China)
```nix
nix.settings.substituters = ["https://mirrors.tuna.tsinghua.edu.cn/nix-channels/store"];
```
## 14. Install nanobot itself
```bash
# As claw user
git clone https://github.com/HKUDS/nanobot.git ~/nanobot-src
cd ~/nanobot-src
uv sync
uv run nanobot onboard # interactive setup wizard
# Populate workspace: SOUL.md, USER.md, memory/MEMORY.md
```
## 15. Apply
Use the safe-switch wrapper to rebuild with health checks:
```bash
sudo /home/claw/.nanobot/workspace/scripts/safe-switch.sh
```
This runs `nixos-rebuild switch`, waits, then verifies the gateway is reachable.
If the health check fails, it automatically rolls back.
## Known quirks
- **sudo path**: Use `/run/wrappers/bin/sudo` inside scripts, not the default PATH's `/run/current-system/sw/bin/sudo` (lacks setuid).
- **systemctl from cron/timers**: Need `XDG_RUNTIME_DIR=/run/user/1000 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus`.
- **Gateway self-restart**: Never `systemctl --user restart nanobot` from within nanobot's own process — it kills the parent. Use `nohup bash -c 'sleep 2 && ...' &`.
- **Rollback**: `cd ~/nanobot-src && git checkout known-good && systemctl --user restart nanobot`.