This document covers deploying ZeroClaw on a Raspberry Pi or other host on your local network, with Telegram and optional webhook channels.
| Mode | Inbound port needed? | Use case |
|---|---|---|
| Telegram polling | No | ZeroClaw polls Telegram API; works from anywhere |
| Matrix sync (including E2EE) | No | ZeroClaw syncs via Matrix client API; no inbound webhook required |
| Discord/Slack | No | Same β outbound only |
| Nostr | No | Connects to relays via WebSocket; outbound only |
| Gateway webhook | Yes | POST /webhook, /whatsapp, /linq, /nextcloud-talk need a public URL |
| Gateway pairing | Yes | If you pair clients via the gateway |
| Alpine/OpenRC service | No | System-wide background service on Alpine Linux |
Key: Telegram, Discord, Slack, and Nostr use outbound connections β ZeroClaw connects to external servers/relays. No port forwarding or public IP required.
- Raspberry Pi (3/4/5) with Raspberry Pi OS
- USB peripherals (Arduino, Nucleo) if using serial transport
- Optional:
rppalfor native GPIO (peripheral-rpifeature)
# Build for RPi (or cross-compile from host)
cargo build --release --features hardware
# Or install via your preferred methodEdit ~/.zeroclaw/config.toml:
[peripherals]
enabled = true
[[peripherals.boards]]
board = "rpi-gpio"
transport = "native"
# Or Arduino over USB
[[peripherals.boards]]
board = "arduino-uno"
transport = "serial"
path = "/dev/ttyACM0"
baud = 115200
[channels_config.telegram]
bot_token = "YOUR_BOT_TOKEN"
allowed_users = []
[gateway]
host = "127.0.0.1"
port = 42617
allow_public_bind = falsezeroclaw daemon --host 127.0.0.1 --port 42617- Gateway binds to
127.0.0.1β not reachable from other machines - Telegram channel works: ZeroClaw polls Telegram API (outbound)
- No firewall or port forwarding needed
To allow other devices on your LAN to hit the gateway (e.g. for pairing or webhooks):
[gateway]
host = "0.0.0.0"
port = 42617
allow_public_bind = truezeroclaw daemon --host 0.0.0.0 --port 42617Security: allow_public_bind = true exposes the gateway to your local network. Only use on trusted LANs.
If you need a public URL (e.g. WhatsApp webhook, external clients):
-
Run gateway on localhost:
zeroclaw daemon --host 127.0.0.1 --port 42617
-
Start a tunnel:
[tunnel] provider = "tailscale" # or "ngrok", "cloudflare"
Or use
zeroclaw tunnel(see tunnel docs). -
ZeroClaw will refuse
0.0.0.0unlessallow_public_bind = trueor a tunnel is active.
Telegram uses long-polling by default:
- ZeroClaw calls
https://api.telegram.org/bot{token}/getUpdates - No inbound port or public IP needed
- Works behind NAT, on RPi, in a home lab
Config:
[channels_config.telegram]
bot_token = "YOUR_BOT_TOKEN"
allowed_users = [] # deny-by-default, bind identities explicitlyRun zeroclaw daemon β Telegram channel starts automatically.
To approve one Telegram account at runtime:
zeroclaw channel bind-telegram <IDENTITY><IDENTITY> can be a numeric Telegram user ID or a username (without @).
Telegram Bot API getUpdates supports only one active poller per bot token.
- Keep one runtime instance for the same token (recommended:
zeroclaw daemonservice). - Do not run
cargo run -- channel startor another bot process at the same time.
If you hit this error:
Conflict: terminated by other getUpdates request
you have a polling conflict. Stop extra instances and restart only one daemon.
Webhook-based channels need a public URL so Meta (WhatsApp) or your client can POST events.
[tunnel]
provider = "tailscale"Tailscale Funnel exposes your gateway via a *.ts.net URL. No port forwarding.
[tunnel]
provider = "ngrok"Or run ngrok manually:
ngrok http 42617
# Use the HTTPS URL for your webhookConfigure Cloudflare Tunnel to forward to 127.0.0.1:42617, then set your webhook URL to the tunnel's public hostname.
- Build with
--features hardware(andperipheral-rpiif using native GPIO) - Configure
[peripherals]and[channels_config.telegram] - Run
zeroclaw daemon --host 127.0.0.1 --port 42617(Telegram works without 0.0.0.0) - For LAN access:
--host 0.0.0.0+allow_public_bind = truein config - For webhooks: use Tailscale, ngrok, or Cloudflare tunnel
ZeroClaw supports OpenRC for Alpine Linux and other distributions using the OpenRC init system. OpenRC services run system-wide and require root/sudo.
- Alpine Linux (or another OpenRC-based distro)
- Root or sudo access
- A dedicated
zeroclawsystem user (created during install)
# Install service (OpenRC is auto-detected on Alpine)
sudo zeroclaw service installThis creates:
- Init script:
/etc/init.d/zeroclaw - Config directory:
/etc/zeroclaw/ - Log directory:
/var/log/zeroclaw/
Manual config copy is usually not required.
sudo zeroclaw service install automatically prepares /etc/zeroclaw, migrates existing runtime state from your user setup when available, and sets ownership/permissions for the zeroclaw service user.
If no prior runtime state is available to migrate, create /etc/zeroclaw/config.toml before starting the service.
# Add to default runlevel
sudo rc-update add zeroclaw default
# Start the service
sudo rc-service zeroclaw start
# Check status
sudo rc-service zeroclaw status| Command | Description |
|---|---|
sudo rc-service zeroclaw start |
Start the daemon |
sudo rc-service zeroclaw stop |
Stop the daemon |
sudo rc-service zeroclaw status |
Check service status |
sudo rc-service zeroclaw restart |
Restart the daemon |
sudo zeroclaw service status |
ZeroClaw status wrapper (uses /etc/zeroclaw config) |
OpenRC routes logs to:
| Log | Path |
|---|---|
| Access/stdout | /var/log/zeroclaw/access.log |
| Errors/stderr | /var/log/zeroclaw/error.log |
View logs:
sudo tail -f /var/log/zeroclaw/error.log# Stop and remove from runlevel
sudo rc-service zeroclaw stop
sudo rc-update del zeroclaw default
# Remove init script
sudo zeroclaw service uninstall- OpenRC is system-wide only (no user-level services)
- Requires
sudoor root for all service operations - The service runs as the
zeroclaw:zeroclawuser (least privilege) - Config must be at
/etc/zeroclaw/config.toml(explicit path in init script) - If the
zeroclawuser does not exist, install will fail with instructions to create it
- Install:
sudo zeroclaw service install - Enable:
sudo rc-update add zeroclaw default - Start:
sudo rc-service zeroclaw start - Verify:
sudo rc-service zeroclaw status - Check logs:
/var/log/zeroclaw/error.log
- channels-reference.md β Channel configuration overview
- matrix-e2ee-guide.md β Matrix setup and encrypted-room troubleshooting
- hardware-peripherals-design.md β Peripherals design
- adding-boards-and-tools.md β Hardware setup and adding boards