Guide

Self-hosting the relay

One lightweight Vapor server behind any TLS reverse proxy. Free, no license keys, and your traffic never touches infrastructure you don't own.

What you need

  • A Linux server (Ubuntu 22.04+ recommended) with Docker and Docker Compose
  • 1 CPU core and 512 MB RAM minimum — 1 GB is comfortable
  • A domain name pointed at the server (the apps connect over WSS, so HTTPS is required)

Quick start

git clone https://github.com/gpambrozio/Gallager
cd Gallager/ClaudeSpyPackage
cp .env.example .env
docker compose up -d

curl http://localhost:8080/health
# {"status":"ok"}

An unedited .env works — every variable has a sane default, licensing is entirely disabled unless you opt in, and push notifications simply stay off until configured. The container binds to 127.0.0.1:8080 only, so nothing is exposed until your reverse proxy is in front of it.

TLS with Caddy

Any reverse proxy that forwards WebSocket upgrades works (the repo's self-hosting doc also has nginx and Traefik configs). Caddy is the least configuration — it provisions Let's Encrypt certificates automatically:

your-domain.com {
    reverse_proxy localhost:8080
}

Verify from outside: curl https://your-domain.com/health.

Point the apps at it

On the Mac: Settings → Remote Access → Server URL. Pair (or re-pair) your iPhone and it uses the same server from then on. No license is needed — the subscription only exists for the hosted relay.

Optional: push notifications

Without APNs configured, everything works while the apps are connected — you just don't get pushes when the phone is away. Enabling them requires an Apple Developer account: create an APNs auth key, drop the .p8 undersecrets/, and set APNS_KEY_PATH, APNS_KEY_ID,APNS_TEAM_ID, APNS_BUNDLE_ID andAPNS_ENVIRONMENT in .env. Note that APNs only accepts pushes signed by the developer team that built the iOS app you're running, so bringing your own key pairs naturally with building the iOS app yourself.

Useful knobs

LOG_LEVELDefaults to warning; the relay logs routing metadata only, never message content.
PAIRING_CODE_EXPIRY_SECONDSHow long pairing codes live. Default 300 (5 minutes).
MIN_CLIENT_VERSIONOptional gate that refuses app versions below a minimum at connect. Unset by default — every client is accepted.
METRICS_TOKENSet to enable a bearer-token-protected Prometheus /metrics endpoint.

Updating

git pull
docker compose down && docker compose build && docker compose up -d
← All docs