mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-04-30 23:05:51 +00:00
181 lines
5.1 KiB
Markdown
181 lines
5.1 KiB
Markdown
# Deployment
|
|
|
|
## Docker
|
|
|
|
> [!TIP]
|
|
> The `-v ~/.nanobot:/home/nanobot/.nanobot` flag mounts your local config directory into the container, so your config and workspace persist across container restarts.
|
|
> The container runs as user `nanobot` (UID 1000). If you get **Permission denied**, fix ownership on the host first: `sudo chown -R 1000:1000 ~/.nanobot`, or pass `--user $(id -u):$(id -g)` to match your host UID. Podman users can use `--userns=keep-id` instead.
|
|
|
|
### Docker Compose
|
|
|
|
```bash
|
|
docker compose run --rm nanobot-cli onboard # first-time setup
|
|
vim ~/.nanobot/config.json # add API keys
|
|
docker compose up -d nanobot-gateway # start gateway
|
|
```
|
|
|
|
```bash
|
|
docker compose run --rm nanobot-cli agent -m "Hello!" # run CLI
|
|
docker compose logs -f nanobot-gateway # view logs
|
|
docker compose down # stop
|
|
```
|
|
|
|
### Docker
|
|
|
|
```bash
|
|
# Build the image
|
|
docker build -t nanobot .
|
|
|
|
# Initialize config (first time only)
|
|
docker run -v ~/.nanobot:/home/nanobot/.nanobot --rm nanobot onboard
|
|
|
|
# Edit config on host to add API keys
|
|
vim ~/.nanobot/config.json
|
|
|
|
# Run gateway (connects to enabled channels, e.g. Telegram/Discord/Mochat)
|
|
docker run -v ~/.nanobot:/home/nanobot/.nanobot -p 18790:18790 nanobot gateway
|
|
|
|
# Or run a single command
|
|
docker run -v ~/.nanobot:/home/nanobot/.nanobot --rm nanobot agent -m "Hello!"
|
|
docker run -v ~/.nanobot:/home/nanobot/.nanobot --rm nanobot status
|
|
```
|
|
|
|
## Linux Service
|
|
|
|
Run the gateway as a systemd user service so it starts automatically and restarts on failure.
|
|
|
|
**1. Find the nanobot binary path:**
|
|
|
|
```bash
|
|
which nanobot # e.g. /home/user/.local/bin/nanobot
|
|
```
|
|
|
|
**2. Create the service file** at `~/.config/systemd/user/nanobot-gateway.service` (replace `ExecStart` path if needed):
|
|
|
|
```ini
|
|
[Unit]
|
|
Description=Nanobot Gateway
|
|
After=network.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
ExecStart=%h/.local/bin/nanobot gateway
|
|
Restart=always
|
|
RestartSec=10
|
|
NoNewPrivileges=yes
|
|
ProtectSystem=strict
|
|
ReadWritePaths=%h
|
|
|
|
[Install]
|
|
WantedBy=default.target
|
|
```
|
|
|
|
**3. Enable and start:**
|
|
|
|
```bash
|
|
systemctl --user daemon-reload
|
|
systemctl --user enable --now nanobot-gateway
|
|
```
|
|
|
|
**Common operations:**
|
|
|
|
```bash
|
|
systemctl --user status nanobot-gateway # check status
|
|
systemctl --user restart nanobot-gateway # restart after config changes
|
|
journalctl --user -u nanobot-gateway -f # follow logs
|
|
```
|
|
|
|
If you edit the `.service` file itself, run `systemctl --user daemon-reload` before restarting.
|
|
|
|
> **Note:** User services only run while you are logged in. To keep the gateway running after logout, enable lingering:
|
|
>
|
|
> ```bash
|
|
> loginctl enable-linger $USER
|
|
> ```
|
|
|
|
## macOS LaunchAgent
|
|
|
|
On macOS, run the gateway as a `launchd` user agent so it starts automatically after login and restarts if it exits unexpectedly.
|
|
|
|
**1. Find the nanobot binary path:**
|
|
|
|
```bash
|
|
which nanobot # e.g. /Users/youruser/.local/bin/nanobot
|
|
```
|
|
|
|
If you installed nanobot with `uv tool`, you may also want the Python path for `ProgramArguments`:
|
|
|
|
```bash
|
|
which python
|
|
```
|
|
|
|
**2. Create the LaunchAgent plist** at `~/Library/LaunchAgents/ai.nanobot.gateway.plist` (replace paths if needed):
|
|
|
|
```xml
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
<plist version="1.0">
|
|
<dict>
|
|
<key>Label</key>
|
|
<string>ai.nanobot.gateway</string>
|
|
|
|
<key>ProgramArguments</key>
|
|
<array>
|
|
<string>/Users/youruser/.local/share/uv/tools/nanobot-ai/bin/python</string>
|
|
<string>/Users/youruser/.local/bin/nanobot</string>
|
|
<string>gateway</string>
|
|
<string>--workspace</string>
|
|
<string>/Users/youruser/.nanobot/workspace</string>
|
|
</array>
|
|
|
|
<key>WorkingDirectory</key>
|
|
<string>/Users/youruser/.nanobot/workspace</string>
|
|
|
|
<key>RunAtLoad</key>
|
|
<true/>
|
|
|
|
<key>KeepAlive</key>
|
|
<dict>
|
|
<key>SuccessfulExit</key>
|
|
<false/>
|
|
</dict>
|
|
|
|
<key>StandardOutPath</key>
|
|
<string>/Users/youruser/.nanobot/logs/gateway.log</string>
|
|
|
|
<key>StandardErrorPath</key>
|
|
<string>/Users/youruser/.nanobot/logs/gateway.error.log</string>
|
|
|
|
<key>EnvironmentVariables</key>
|
|
<dict>
|
|
<key>PATH</key>
|
|
<string>/Users/youruser/.local/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
|
|
<key>PYTHONUNBUFFERED</key>
|
|
<string>1</string>
|
|
</dict>
|
|
</dict>
|
|
</plist>
|
|
```
|
|
|
|
**3. Load and start it:**
|
|
|
|
```bash
|
|
mkdir -p ~/.nanobot/logs
|
|
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/ai.nanobot.gateway.plist
|
|
launchctl enable gui/$(id -u)/ai.nanobot.gateway
|
|
launchctl kickstart -k gui/$(id -u)/ai.nanobot.gateway
|
|
```
|
|
|
|
**Common operations:**
|
|
|
|
```bash
|
|
launchctl list | grep ai.nanobot.gateway
|
|
launchctl kickstart -k gui/$(id -u)/ai.nanobot.gateway
|
|
launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/ai.nanobot.gateway.plist
|
|
log stream --process nanobot
|
|
```
|
|
|
|
If you edit the plist itself, run `launchctl bootout ...` and `launchctl bootstrap ...` again so `launchd` reloads the updated definition.
|
|
|
|
> **Note:** if `launchctl kickstart` fails with an "address already in use" error, you probably still have a manually started `nanobot gateway` process running on the same port. Stop the manual process first, then kickstart the LaunchAgent again.
|