Private relay
Source: docs/private-relay.md · USER
Users can run their own relay server and keep the same WebChat GUI, CLI, groups, files, voice, receive-language translation, floating language keyboard, and session behavior.
Server Setup
On the server:
cd /path/to/WebChat
cp relay/.env.example relay/.env.local
mkdir -p relay/data relay/pchat_uploads
WEBCHAT_RELAY_PORT=5110 ./start_relay.sh
The relay listens on:
http://SERVER_IP:5110
For real public use, put HTTPS in front of it with Caddy, Nginx, Cloudflare, or another reverse proxy:
https://chat-relay.example.com
Plain Docker (fallback — ships source server.py)
cd /path/to/WebChat
cp relay/.env.example relay/.env.local
docker compose -f docker-compose.private-relay.yml up -d --build
Use this for user-owned private servers where the operator wants a simple Docker deployment and does not want the plain relay source file inside the runtime container.
Downloadable Package
Build a package for users to download and install:
scripts/package_private_relay.sh
More details:
docs/private-server-install.md
Production Notes
Set this in relay/.env.local for public servers:
PCHAT_DEV_EXPOSE_CODES=false
Configure SMTP so users can receive login codes:
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USERNAME=webchat@example.com
SMTP_PASSWORD=change-me
SMTP_FROM=webchat@example.com
Retention / TTL knobs
All values in seconds. 0 disables that specific expiry. Defaults are sane for
most deploys; tighten for higher-privacy operation.
# Session tokens (auth) — clients re-auth via email code after this.
PCHAT_SESSION_TTL_SEC=2592000 # 30 days
# Queued (undelivered) messages — housekeeping drops anything older.
QUEUE_STALE_TTL_SEC=259200 # 3 days (non-PCHAT: SMS/WA/TG/EMAIL/NOTIFY)
PCHAT_QUEUE_STALE_TTL_SEC=604800 # 7 days (PCHAT)
# Per-housekeeping-pass throttle (don't run more often than this).
QUEUE_HOUSEKEEPING_INTERVAL_SEC=60
# Uploaded files (images / voice / attachments) in pchat_uploads/.
PCHAT_UPLOAD_TTL_SEC=2592000 # 30 days
# Pending group-join requests that nobody approved/rejected.
PCHAT_JOIN_REQUEST_TTL_SEC=2592000 # 30 days
# Message text after delivery. One of:
# full (keep text forever)
# scrub_content_on_final (clear text after delivered — DEFAULT, recommended)
# scrub_all_on_final (clear text + destination after delivered)
# scrub_content_on_claim (clear text as soon as recipient claims, before delivery confirmed)
# scrub_all_on_claim (clear text + destination on claim)
MESSAGE_RETENTION_MODE=scrub_content_on_final
Keep these directories persistent:
relay/data
relay/pchat_uploads
Connect Users
In WebChat GUI:
- Open Settings.
- Open
Advanced relay, phone bridge, translation. - Choose
Private Server Relay. - Set
Relay Server URLto your server URL. - Save and sign in with email.
Or share a launch link:
scripts/private_relay_link.py \
--site https://your-webchat-site.example.com/app/webchat/chat.html \
--relay https://chat-relay.example.com
Users opening that link will use the private relay, while the rest of the app works the same.