How to Set Up a Reverse Proxy with WebSocket Support for TREK Production Deployments
To deploy TREK behind a reverse proxy, you must configure WebSocket upgrades for the /ws endpoint and increase the body size limit to at least 500 MiB to support backup-restore operations.
TREK is a real-time collaboration platform that requires a persistent WebSocket connection for live features. When running production deployments behind Nginx or Caddy, proper proxy configuration ensures the Express application receives the correct headers and maintains long-lived connections. This guide covers the exact environment variables and proxy directives required based on the TREK source code.
Understanding TREK's WebSocket Requirements
TREK exposes its real-time collaboration layer at the /ws endpoint implemented in server/src/websocket.ts. The application expects the reverse proxy to handle transport-layer security while preserving the connection characteristics needed for WebSocket handshakes.
The /ws Endpoint
The WebSocket handler requires HTTP/1.1 protocol upgrades to remain persistent. Unlike standard HTTP requests, these connections must stay open for extended periods—up to 24 hours in production environments—to maintain real-time synchronization between clients.
Large Payload Handling
Backup and restore operations in TREK transmit archives that can exceed 500 MiB. The default proxy body size limits (typically 1 MiB in Nginx) will block these operations unless explicitly raised.
Required Environment Variables
TREK reads specific environment variables to adapt its behavior behind a TLS-terminating proxy. Configure these in your production environment or docker-compose.yml:
| Variable | Purpose | Production Value |
|---|---|---|
FORCE_HTTPS |
Enables HTTP to HTTPS redirects and HSTS headers | true |
TRUST_PROXY |
Sets trusted hop count for Express to read real client IP from X-Forwarded-For |
1 |
COOKIE_SECURE |
Sets Secure flag on trek_session cookie (auto-enabled when FORCE_HTTPS or NODE_ENV=production is set) |
true |
ALLOWED_ORIGINS |
CORS whitelist for cross-origin requests | https://your.trek.domain |
These variables are documented in [wiki/Environment-Variables.md](https://github.com/mauriceboe/TREK/blob/main/wiki/Environment-Variables.md).
Nginx Configuration for TREK
The following configuration handles TLS termination, WebSocket proxying, and large file uploads. Key directives include proxy_read_timeout 86400 to keep connections alive and client_max_body_size 500m for backup operations.
# HTTP → HTTPS redirect (optional, but recommended)
server {
listen 80;
server_name trek.yourdomain.com;
return 301 https://$host$request_uri;
}
# TLS‑enabled reverse‑proxy
server {
listen 443 ssl http2;
server_name trek.yourdomain.com;
# Paths to your TLS certificate and private key
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
# -------------------------------------------------
# WebSocket endpoint – /ws
# -------------------------------------------------
location /ws {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Keep the WS connection alive (24 h)
proxy_read_timeout 86400;
# Allow large backup‑restore uploads
client_max_body_size 500m;
}
# -------------------------------------------------
# All other HTTP traffic
# -------------------------------------------------
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Large uploads (e.g. backup restores)
client_max_body_size 500m;
}
}
According to the [wiki/Reverse-Proxy.md](https://github.com/mauriceboe/TREK/blob/main/wiki/Reverse-Proxy.md) documentation, the X-Forwarded-Proto $scheme header is critical for TREK's FORCE_HTTPS logic to determine the original request protocol.
Caddy Configuration for TREK
Caddy automatically handles WebSocket upgrades, making the configuration significantly shorter. You only need to specify the body size limit and upstream address.
trek.yourdomain.com {
# Enable TLS (Caddy obtains/renews certs automatically)
tls you@example.com
# Large backup‑restore payloads
request_body max_size 500mb
# Reverse‑proxy all traffic to the TREK backend
reverse_proxy localhost:3000
}
If you terminate TLS upstream in a load balancer, omit the tls directive while keeping the request_body limit to ensure backup-restore functionality remains intact.
Key Implementation Files
Understanding these source files helps debug proxy configuration issues:
server/src/websocket.ts– Implements the/wsendpoint and defines the WebSocket path used by the proxy.client/vite.config.js– Contains development proxy settings for/wsthat mirror production requirements.docker-compose.yml– Demonstrates production environment variable injection for TLS-ready deployments.wiki/Reverse-Proxy.md– Official documentation with additional Nginx and Caddy examples.
Summary
- WebSocket support requires forwarding
UpgradeandConnectionheaders with extended timeouts (24 hours) for the/wsendpoint. - Body size limits must be set to at least 500 MiB in both Nginx (
client_max_body_size) and Caddy (request_body max_size) to handle backup-restore operations. - Environment variables including
FORCE_HTTPS,TRUST_PROXY, andALLOWED_ORIGINSmust be configured so TREK trusts the proxy and generates secure cookies. - Header forwarding via
X-Forwarded-ProtoandX-Forwarded-Forensures TREK correctly identifies client IPs and protocol schemes.
Frequently Asked Questions
Why does TREK require a 24-hour proxy timeout?
TREK maintains persistent WebSocket connections for real-time collaboration features. The proxy_read_timeout 86400 directive in Nginx (or equivalent in Caddy) prevents the proxy from closing idle connections, ensuring users stay synchronized without frequent reconnections.
Can I use a different body size limit than 500 MiB?
While you can adjust the limit, 500 MiB is the recommended minimum based on the backup-restore archive sizes supported by TREK. Setting this lower in client_max_body_size or request_body will cause HTTP 413 errors when users attempt to restore large project archives.
How does TREK handle HTTPS behind a reverse proxy?
When FORCE_HTTPS is set to true, TREK relies on the X-Forwarded-Proto header to determine if the original request used HTTPS. This header must be forwarded by your proxy (as shown in the Nginx example) to trigger HSTS headers and secure cookie flags correctly.
Does Caddy require explicit WebSocket headers?
No. Caddy automatically detects WebSocket upgrade requests and handles the Upgrade and Connection headers internally. You only need to ensure the request_body max_size is configured for large uploads, making Caddy configurations significantly shorter than Nginx equivalents.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →