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

To run TREK behind a reverse proxy, you must enable WebSocket upgrades on the /ws endpoint, set proxy_read_timeout to 86400 in Nginx (or rely on Caddy’s automatic handling), and increase body size limits to 500 MiB to support backup restores.

TREK relies on a persistent WebSocket connection at the /ws endpoint for real-time collaboration features. When placing TREK behind a TLS-terminating reverse proxy, you must ensure that Upgrade and Connection headers are forwarded correctly and that timeout settings accommodate long-lived connections. The application also requires specific environment variables to interpret forwarded headers and enforce secure cookies.

Environment Variables for Proxy Configuration

TREK reads several environment variables to function correctly behind a reverse proxy. These are documented in [wiki/Environment-Variables.md](https://github.com/mauriceboe/TREK/blob/main/wiki/Environment-Variables.md).

  • FORCE_HTTPS: Forces HTTP to HTTPS redirects and enables HSTS. Set to true in production.
  • TRUST_PROXY: Specifies the number of trusted proxy hops for Express to read the real client IP from X-Forwarded-For. Typically set to 1.
  • COOKIE_SECURE: Automatically enables the Secure flag on the trek_session cookie when FORCE_HTTPS is true or NODE_ENV is set to production.
  • ALLOWED_ORIGINS: CORS whitelist for accepted origins. Set to your domain, e.g., https://your.trek.domain.

Nginx Reverse Proxy Configuration

For Nginx, you must explicitly handle the WebSocket upgrade headers and extend the read timeout to prevent connection drops. The configuration is documented in [wiki/Reverse-Proxy.md](https://github.com/mauriceboe/TREK/blob/main/wiki/Reverse-Proxy.md).


# 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;

    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;
    }
}

Critical directives explained:

  • proxy_read_timeout 86400: Keeps the WebSocket connection alive for up to 24 hours, preventing timeouts during idle periods.
  • client_max_body_size 500m: Lifts the default 1 MiB limit, which is required for backup restore archives that can exceed 500 MiB.
  • X-Forwarded-Proto $scheme: Tells TREK whether the original request was HTTPS, enabling proper behavior when FORCE_HTTPS is active.

Caddy Reverse Proxy Configuration

Caddy automatically handles WebSocket upgrades, making the configuration significantly simpler. You only need to specify the body size limit for large restores.

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 prefer to terminate TLS elsewhere (e.g., at a load balancer), omit the tls block. Caddy will still correctly proxy WebSocket traffic to /ws without additional header configuration.

Core Implementation Details

Understanding the source files helps verify that your proxy configuration matches the application's expectations.

Summary

  • WebSocket Path: TREK uses /ws for real-time collaboration; this endpoint must pass Upgrade and Connection headers.
  • Nginx Requirements: Explicitly set proxy_http_version 1.1, forward upgrade headers, and configure proxy_read_timeout 86400 and client_max_body_size 500m.
  • Caddy Simplicity: Caddy auto-detects WebSocket upgrades; only request_body max_size 500mb is required.
  • Environment Variables: Set FORCE_HTTPS=true, TRUST_PROXY=1, and ALLOWED_ORIGINS to ensure TREK correctly handles secure cookies and client IPs.

Frequently Asked Questions

Why does TREK require WebSocket support on the /ws endpoint?

TREK implements real-time collaboration features through a persistent WebSocket connection handled in [server/src/websocket.ts](https://github.com/mauriceboe/TREK/blob/main/server/src/websocket.ts). Without proper WebSocket proxying, the application cannot synchronize data between clients.

What is the minimum client_max_body_size required for Nginx?

You must set client_max_body_size 500m (or higher) in Nginx. TREK’s backup and restore functionality handles archives that can be 500 MiB or larger, and the default 1 MiB limit will cause upload failures.

Does Caddy require manual WebSocket header configuration?

No. Caddy automatically detects the Upgrade: websocket header and handles the connection upgrade without manual proxy_set_header directives. You only need to configure the request_body max_size and reverse_proxy directives.

How does TREK enforce HTTPS when behind a reverse proxy?

When you set FORCE_HTTPS=true, TREK uses the X-Forwarded-Proto header to determine if the original request was HTTPS. If the header indicates HTTP, the application redirects to HTTPS and sets the Secure flag on session cookies.

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 →