Skip to content

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.

ModeInbound port needed?Notes
Telegram pollingNoRevka polls the Telegram API; works from anywhere
Matrix sync (incl. E2EE)NoSyncs via the Matrix client API; no webhook
Discord / SlackNoOutbound only
NostrNoConnects to relays over WebSocket; outbound only
Gateway webhookYesPOST /webhook, /whatsapp, /linq, /nextcloud-talk need a public URL
Gateway pairingYesIf you pair remote clients via the gateway

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.

~/.revka/config.toml
[gateway]
host = "0.0.0.0"
port = 42617
allow_public_bind = true

You can override the bind address per run from the CLI:

Terminal window
revka daemon --host 127.0.0.1 # localhost only (default)
revka daemon --host 0.0.0.0 --port 42617 # LAN access
SettingEnv overrideDefaultMeaning
gateway.hostREVKA_GATEWAY_HOST127.0.0.1Bind address
gateway.portREVKA_GATEWAY_PORT42617Listen port
gateway.allow_public_bindREVKA_ALLOW_PUBLIC_BINDfalseRequired to bind a non-loopback address

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.

Prebuilt binaries are published for both Raspberry Pi architectures, so you usually do not need to compile on the device:

TargetBoard
aarch64-unknown-linux-gnuRaspberry Pi 4 / 5 (64-bit)
armv7-unknown-linux-gnueabihfRaspberry Pi 2 / 3 (ARMv7)
arm-unknown-linux-gnueabihfOlder 32-bit ARM

If you do build locally (for example to enable GPIO), add the hardware features:

Terminal window
# USB / serial device support
cargo build --release --features hardware
# Native Raspberry Pi GPIO via rppal
cargo build --release --features hardware,peripheral-rpi
Cargo featureEnables
hardwareUSB / serial device support
peripheral-rpiNative RPi GPIO (via rppal)

Configure GPIO, serial peripherals, and Telegram

Section titled “Configure GPIO, serial peripherals, and Telegram”
~/.revka/config.toml
[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 = 42617
allow_public_bind = false
  1. Start the daemon bound to localhost — Telegram still works because it polls outbound:

    Terminal window
    revka daemon --host 127.0.0.1 --port 42617
  2. Approve one Telegram account at runtime (numeric user ID or username without @):

    Terminal window
    revka channel bind-telegram <IDENTITY>
  3. To let other LAN devices reach the dashboard or pair, switch to 0.0.0.0 and set allow_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 — 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.

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 = true
http_url = "http://proxy.example.com:8080"
https_url = "http://proxy.example.com:8080"
scope = "services"
services = ["provider.anthropic", "channel.telegram"]
KeyEnv overrideDefaultMeaning
enabledREVKA_PROXY_ENABLEDfalseMaster switch
http_urlREVKA_HTTP_PROXYunsetHTTP proxy URL
https_urlREVKA_HTTPS_PROXYunsetHTTPS proxy URL
all_proxyREVKA_ALL_PROXYunsetFallback proxy for all protocols (SOCKS5)
no_proxyREVKA_NO_PROXYunsetHosts that bypass the proxy
scopeREVKA_PROXY_SCOPE"revka"environment | revka | services
servicesREVKA_PROXY_SERVICES[]Comma-separated service keys (when scope = "services")

Allowed proxy URL schemes are http, https, socks5, and socks5h.

The scope field decides how far the proxy reaches:

ScopeAffectsExports env vars?Use when
revkaRevka’s own outbound HTTP clientsNoNormal runtime proxying without process-level side effects
servicesOnly the listed service keys / selectorsNoSurgical routing for specific providers, channels, or tools
environmentRuntime plus process HTTP_PROXY / HTTPS_PROXY / ALL_PROXY / NO_PROXYYesSidecars 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 = true
http_url = "http://127.0.0.1:7890"
scope = "services"
services = ["provider.*", "channel.telegram"] # only LLM providers + Telegram

Manage 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.

ParamTypeUsed byMeaning
actionstringallOne of the actions above (default get)
enabledboolsetEnable or disable the proxy
scopestringsetenvironment | revka | services
http_proxy / https_proxy / all_proxystringsetProxy URLs
no_proxystring or arraysetNO_PROXY entries
servicesstring or arraysetService selectors (when scope = services)
clear_envbooldisableAlso clear process proxy env vars

Follow this standard, reversible workflow for every proxy change: inspect, discover, apply, verify, roll back if needed.

  1. Inspect current state and discover valid service keys.

    {"action": "get"}
    {"action": "list_services"}
  2. 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"]}
  3. Verify the runtime and environment snapshots.

    {"action": "get"}
  4. 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
  1. Use a prebuilt aarch64/armv7 binary, or build with --features hardware (add peripheral-rpi for native GPIO).
  2. Configure [peripherals] and [channels_config.telegram] in ~/.revka/config.toml.
  3. Run revka daemon --host 127.0.0.1 --port 42617 — Telegram works without a public bind.
  4. For LAN access, set --host 0.0.0.0 plus allow_public_bind = true.
  5. For webhooks, front the gateway with a Tailscale, ngrok, or Cloudflare tunnel.
  6. Keep a single poller per Telegram bot token.