How to Configure a Reverse Proxy (Nginx or Caddy) with WebSocket Support for TREK

To run TREK behind a reverse proxy, you must enable WebSocket upgrades on the /ws endpoint, increase the body size limit to at least 500 MiB for backup restores, and set TRUST_PROXY=1 and FORCE_HTTPS=true environment variables.

TREK is a real-time collaboration application that relies on persistent WebSocket connections for live updates. When deploying behind a TLS-terminating reverse proxy, proper header forwarding and connection timeouts are essential for functionality. This guide covers the exact configuration requirements for Nginx and Caddy based on the official TREK source code and documentation.

Why WebSocket Support Is Critical for TREK

TREK establishes persistent connections at the /ws endpoint to synchronize state between clients and the server. In server/src/websocket.ts, the application initializes the WebSocket server and expects the proxy to handle the protocol upgrade.

If the reverse proxy blocks or terminates the Upgrade header, real-time features fail silently. You must also configure extended timeouts because collaboration sessions can remain active for hours or days.

Required Environment Variables

TREK reads specific environment variables to trust headers from your reverse proxy and enforce secure cookies. Configure these before starting the application:

  • FORCE_HTTPS: Set to true to enable HTTP-to-HTTPS redirects and HSTS headers. This ensures the application recognizes secure connections even when TLS terminates at the proxy.
  • TRUST_PROXY: Set to 1 (or higher if behind multiple proxies) to instruct Express to parse X-Forwarded-For headers and identify the real client IP.
  • COOKIE_SECURE: Automatically enabled when FORCE_HTTPS is true or NODE_ENV=production, but can be set explicitly to enforce the Secure flag on the trek_session cookie.
  • ALLOWED_ORIGINS: A comma-separated CORS whitelist (e.g., https://trek.yourdomain.com) to prevent cross-origin errors when the frontend connects via the proxy.

These variables are documented in wiki/Environment-Variables.md and consumed by the Express server configuration.

Nginx Configuration

For Nginx, you must explicitly handle the WebSocket upgrade headers and increase body size limits. The following configuration implements both requirements while forwarding the necessary headers to TREK running on localhost:3000.


# HTTP to HTTPS redirect

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;

    ssl_certificate /path/to/fullchain.pem;
    ssl_certificate_key /path/to/privkey.pem;

    # WebSocket endpoint

    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 connection alive for 24 hours

        proxy_read_timeout 86400;
        
        # Support large backup restores

        client_max_body_size 500m;
    }

    # All other 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;
        client_max_body_size 500m;
    }
}

Handling the WebSocket Endpoint

The /ws location block in the configuration above is mandatory. The proxy_set_header Upgrade $http_upgrade and proxy_set_header Connection "upgrade" lines allow Nginx to forward the protocol upgrade request from the client to the TREK backend.

The proxy_read_timeout 86400 directive (24 hours) prevents Nginx from closing idle WebSocket connections, which is crucial for long-running collaboration sessions.

Supporting Large File Uploads

TREK's backup and restore functionality can upload archives exceeding 500 MiB. The client_max_body_size 500m directive overrides Nginx's default 1 MiB limit, preventing 413 Payload Too Large errors during restore operations. This must be set in both the /ws location and the general / location to cover all upload paths.

Caddy Configuration

Caddy handles WebSocket upgrades automatically, resulting in a cleaner configuration. However, you must still explicitly configure the body size limit for backup restores.

trek.yourdomain.com {
    tls you@example.com
    
    # Allow large backup uploads

    request_body max_size 500mb
    
    # Proxy all traffic including WebSocket

    reverse_proxy localhost:3000
}

If you terminate TLS upstream (e.g., at a cloud load balancer), omit the tls directive. Caddy will still correctly proxy WebSocket traffic without additional Upgrade header configuration, unlike Nginx.

Verifying Your Proxy Setup

After configuring your proxy, verify that headers are correctly forwarded by checking the TREK application logs. The server should report the client's real IP address rather than the proxy's internal IP.

During development, you can inspect the proxy configuration in client/vite.config.js, which demonstrates how the Vite dev server proxies /ws to the backend. This file serves as a reference for the expected header behavior.

Summary

  • WebSocket endpoint: The /ws path requires Upgrade and Connection header forwarding in Nginx; Caddy handles this automatically.
  • Body size limits: Set client_max_body_size 500m (Nginx) or request_body max_size 500mb (Caddy) to support backup restores.
  • Environment variables: Set TRUST_PROXY=1 and FORCE_HTTPS=true so TREK correctly identifies secure connections and client IPs.
  • Timeouts: Configure proxy_read_timeout 86400 in Nginx to prevent WebSocket disconnections during idle periods.

Frequently Asked Questions

Does TREK require a specific reverse proxy?

No, TREK works with any reverse proxy that supports WebSocket upgrades and large request bodies. The repository provides official examples for Nginx and Caddy in wiki/Reverse-Proxy.md, but HAProxy, Traefik, or cloud load balancers will work provided they forward the X-Forwarded-Proto and X-Forwarded-For headers.

What is the maximum file size for backup restores?

The default configuration supports archives up to 500 MiB. You can adjust this limit by modifying the client_max_body_size (Nginx) or request_body max_size (Caddy) directive to match your storage capacity. Larger restores may also require increasing the proxy_read_timeout to prevent disconnections during slow uploads.

Why does TREK need the X-Forwarded-Proto header?

TREK uses the X-Forwarded-Proto header to determine whether the original client connection used HTTPS. This is essential when FORCE_HTTPS is enabled, as the application must know to send secure cookies and redirect HTTP requests even though the connection between the proxy and TREK uses plain HTTP.

Can I change the WebSocket endpoint path from /ws?

The /ws path is hardcoded in server/src/websocket.ts and referenced in the client-side connection logic. Changing it would require modifying the source code and rebuilding the application. For standard deployments, keep the proxy configuration pointing to /ws as shown in the documentation.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →