5.1 KiB
Deployment
Docker
Tip
The
-v ~/.nanobot:/home/nanobot/.nanobotflag mounts your local config directory into the container, so your config and workspace persist across container restarts. The container runs as usernanobot(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-idinstead.
Docker Compose
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
docker compose run --rm nanobot-cli agent -m "Hello!" # run CLI
docker compose logs -f nanobot-gateway # view logs
docker compose down # stop
Docker
# 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:
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):
[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:
systemctl --user daemon-reload
systemctl --user enable --now nanobot-gateway
Common operations:
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:
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:
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:
which python
2. Create the LaunchAgent plist at ~/Library/LaunchAgents/ai.nanobot.gateway.plist (replace paths if needed):
<?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:
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:
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 kickstartfails with an "address already in use" error, you probably still have a manually startednanobot gatewayprocess running on the same port. Stop the manual process first, then kickstart the LaunchAgent again.