Network deployment, Raspberry Pi & proxy
LAN binding, polling vs webhook channels, ARM targets, Raspberry Pi embedded deployment, and outbound proxy routing.
This page covers running Revka on a local network or a low-power ARM board, and routing its outbound traffic through a proxy. Use it when you deploy to a Raspberry Pi or home-lab host, need to decide between polling and webhook channels, or have to send Revka’s traffic through a corporate or air-gapped proxy.
The single revka binary runs everywhere — see Runtime modes, adapters & resource limits for the native vs. Docker adapter, and Run as a background service to keep the daemon alive across reboots.
Choose a channel by inbound-port requirement
Section titled “Choose a channel by inbound-port requirement”The biggest network decision is whether your channels need an inbound port. Polling-style channels make only outbound connections, so they work behind NAT, on a Raspberry Pi, or in a home lab with no port forwarding. Webhook channels need a public HTTPS URL so the remote service can POST events to you.
| Mode | Inbound port needed? | Notes |
|---|---|---|
| Telegram polling | No | Revka polls the Telegram API; works from anywhere |
| Matrix sync (incl. E2EE) | No | Syncs via the Matrix client API; no webhook |
| Discord / Slack | No | Outbound only |
| Nostr | No | Connects to relays over WebSocket; outbound only |
| Gateway webhook | Yes | POST /webhook, /whatsapp, /linq, /nextcloud-talk need a public URL |
| Gateway pairing | Yes | If you pair remote clients via the gateway |
Network deployment modes (bind addresses)
Section titled “Network deployment modes (bind addresses)”The gateway can bind to:
127.0.0.1— localhost only (the default; not reachable from other machines)0.0.0.0— all IPv4 interfaces (LAN access)[::]— all IPv6 interfaces (the default inside Docker containers)
Binding to a non-loopback address is guarded: the CLI and daemon refuse to bind to anything other than loopback unless allow_public_bind = true is set, or a tunnel is active.
[gateway]host = "0.0.0.0"port = 42617allow_public_bind = trueYou can override the bind address per run from the CLI:
revka daemon --host 127.0.0.1 # localhost only (default)revka daemon --host 0.0.0.0 --port 42617 # LAN access| Setting | Env override | Default | Meaning |
|---|---|---|---|
gateway.host | REVKA_GATEWAY_HOST | 127.0.0.1 | Bind address |
gateway.port | REVKA_GATEWAY_PORT | 42617 | Listen port |
gateway.allow_public_bind | REVKA_ALLOW_PUBLIC_BIND | false | Required to bind a non-loopback address |
Raspberry Pi & embedded deployment
Section titled “Raspberry Pi & embedded deployment”Revka runs on ARMv7 and ARM64 (aarch64) Linux, including Raspberry Pi 3 / 4 / 5 on Raspberry Pi OS. Telegram polling needs no inbound port, and USB-attached serial peripherals (Arduino, STM32 Nucleo) work over the native runtime.
ARMv7 / aarch64 prebuilt binaries
Section titled “ARMv7 / aarch64 prebuilt binaries”Prebuilt binaries are published for both Raspberry Pi architectures, so you usually do not need to compile on the device:
| Target | Board |
|---|---|
aarch64-unknown-linux-gnu | Raspberry Pi 4 / 5 (64-bit) |
armv7-unknown-linux-gnueabihf | Raspberry Pi 2 / 3 (ARMv7) |
arm-unknown-linux-gnueabihf | Older 32-bit ARM |
Build from source with hardware support
Section titled “Build from source with hardware support”If you do build locally (for example to enable GPIO), add the hardware features:
# USB / serial device supportcargo build --release --features hardware
# Native Raspberry Pi GPIO via rppalcargo build --release --features hardware,peripheral-rpi| Cargo feature | Enables |
|---|---|
hardware | USB / serial device support |
peripheral-rpi | Native RPi GPIO (via rppal) |
Configure GPIO, serial peripherals, and Telegram
Section titled “Configure GPIO, serial peripherals, and Telegram”[peripherals]enabled = true
# Native RPi GPIO[[peripherals.boards]]board = "rpi-gpio"transport = "native"
# Or an Arduino over USB-serial[[peripherals.boards]]board = "arduino-uno"transport = "serial"path = "/dev/ttyACM0"baud = 115200
[channels_config.telegram]bot_token = "YOUR_BOT_TOKEN"allowed_users = [] # deny-by-default; bind identities explicitly
[gateway]host = "127.0.0.1"port = 42617allow_public_bind = falseRun the daemon
Section titled “Run the daemon”-
Start the daemon bound to localhost — Telegram still works because it polls outbound:
Terminal window revka daemon --host 127.0.0.1 --port 42617 -
Approve one Telegram account at runtime (numeric user ID or username without
@):Terminal window revka channel bind-telegram <IDENTITY> -
To let other LAN devices reach the dashboard or pair, switch to
0.0.0.0and setallow_public_bind = true(see bind addresses above).
For GPIO tooling, board references, and a dedicated Pi walkthrough, see Raspberry Pi (self-hosted), GPIO tools, and Supported boards reference. On Alpine/OpenRC boards, install the system service with sudo revka service install — details in Run as a background service.
Webhook channels (public URL)
Section titled “Webhook channels (public URL)”Webhook channels — WhatsApp Cloud API, Nextcloud Talk, and the generic ingress — need a public HTTPS endpoint. The recommended pattern is to keep the gateway on 127.0.0.1 and front it with a tunnel rather than binding publicly:
[tunnel]provider = "tailscale" # or "ngrok", "cloudflare", "pinggy", "openvpn", "custom"Point your webhook URL at the tunnel’s public hostname. The full provider list, tokens, and config keys are in Expose your gateway with a tunnel; the ingress endpoints are documented in Webhook ingress.
Outbound proxy routing — [proxy]
Section titled “Outbound proxy routing — [proxy]”Enterprise and air-gapped deployments often must route Revka’s outbound HTTP/HTTPS/SOCKS5 traffic through a proxy. The [proxy] section controls this, including per-service routing so only chosen providers, channels, or tools traverse the proxy.
[proxy]enabled = truehttp_url = "http://proxy.example.com:8080"https_url = "http://proxy.example.com:8080"scope = "services"services = ["provider.anthropic", "channel.telegram"]| Key | Env override | Default | Meaning |
|---|---|---|---|
enabled | REVKA_PROXY_ENABLED | false | Master switch |
http_url | REVKA_HTTP_PROXY | unset | HTTP proxy URL |
https_url | REVKA_HTTPS_PROXY | unset | HTTPS proxy URL |
all_proxy | REVKA_ALL_PROXY | unset | Fallback proxy for all protocols (SOCKS5) |
no_proxy | REVKA_NO_PROXY | unset | Hosts that bypass the proxy |
scope | REVKA_PROXY_SCOPE | "revka" | environment | revka | services |
services | REVKA_PROXY_SERVICES | [] | Comma-separated service keys (when scope = "services") |
Allowed proxy URL schemes are http, https, socks5, and socks5h.
Scope: environment / revka / services
Section titled “Scope: environment / revka / services”The scope field decides how far the proxy reaches:
| Scope | Affects | Exports env vars? | Use when |
|---|---|---|---|
revka | Revka’s own outbound HTTP clients | No | Normal runtime proxying without process-level side effects |
services | Only the listed service keys / selectors | No | Surgical routing for specific providers, channels, or tools |
environment | Runtime plus process HTTP_PROXY / HTTPS_PROXY / ALL_PROXY / NO_PROXY | Yes | Sidecars or subprocesses that read proxy env vars |
When scope = "services", you select targets by exact key or wildcard. Supported keys include provider.anthropic, provider.openai, provider.compatible, channel.telegram, channel.discord, tool.browser, tool.web_search, memory.embeddings, tunnel.custom, and transcription.groq, among others. Wildcards provider.*, channel.*, and tool.* are supported.
[proxy]enabled = truehttp_url = "http://127.0.0.1:7890"scope = "services"services = ["provider.*", "channel.telegram"] # only LLM providers + TelegramManage the proxy at runtime — proxy_config tool
Section titled “Manage the proxy at runtime — proxy_config tool”The agent can read and change proxy settings live through the proxy_config tool, without editing config.toml by hand. This is ideal when an operator needs the agent to switch proxy behavior on demand.
Actions: get, set, disable, list_services, apply_env, clear_env.
| Param | Type | Used by | Meaning |
|---|---|---|---|
action | string | all | One of the actions above (default get) |
enabled | bool | set | Enable or disable the proxy |
scope | string | set | environment | revka | services |
http_proxy / https_proxy / all_proxy | string | set | Proxy URLs |
no_proxy | string or array | set | NO_PROXY entries |
services | string or array | set | Service selectors (when scope = services) |
clear_env | bool | disable | Also clear process proxy env vars |
Proxy Agent Playbook
Section titled “Proxy Agent Playbook”Follow this standard, reversible workflow for every proxy change: inspect, discover, apply, verify, roll back if needed.
-
Inspect current state and discover valid service keys.
{"action": "get"}{"action": "list_services"} -
Apply the scope you need.
Route Revka’s provider/channel/tool HTTP traffic without exporting process env vars:
{"action": "set", "enabled": true, "scope": "revka","http_proxy": "http://127.0.0.1:7890","https_proxy": "http://127.0.0.1:7890","no_proxy": ["localhost", "127.0.0.1"]}Proxy only specific providers/tools/channels (exact keys or selectors):
{"action": "set", "enabled": true, "scope": "services","services": ["provider.openai", "tool.http_request", "channel.telegram"],"all_proxy": "socks5h://127.0.0.1:1080","no_proxy": ["localhost", "127.0.0.1", ".internal"]}Export process-wide proxy env vars for subprocesses that read them, then apply:
{"action": "set", "enabled": true, "scope": "environment","http_proxy": "http://127.0.0.1:7890","https_proxy": "http://127.0.0.1:7890","no_proxy": "localhost,127.0.0.1,.internal"}{"action": "apply_env"} -
Verify the runtime and environment snapshots.
{"action": "get"} -
Roll back if behavior is not what you expect.
{"action": "disable"} // disable proxy (safe default){"action": "disable", "clear_env": true} // also clear exported env vars{"action": "clear_env"} // keep proxy on, drop env exports only
RPi deployment checklist
Section titled “RPi deployment checklist”- Use a prebuilt
aarch64/armv7binary, or build with--features hardware(addperipheral-rpifor native GPIO). - Configure
[peripherals]and[channels_config.telegram]in~/.revka/config.toml. - Run
revka daemon --host 127.0.0.1 --port 42617— Telegram works without a public bind. - For LAN access, set
--host 0.0.0.0plusallow_public_bind = true. - For webhooks, front the gateway with a Tailscale, ngrok, or Cloudflare tunnel.
- Keep a single poller per Telegram bot token.