How to Set Up SSL for TREK with Nginx: Complete Configuration Guide
Place TREK behind an Nginx reverse proxy that terminates TLS on port 443, proxies HTTP traffic to localhost:3000, and handles WebSocket upgrades for the /ws endpoint while setting TRUST_PROXY=1 in your environment.
TREK is a self-hosted Node.js application that runs on port 3000 by default and uses WebSockets for real-time collaboration features. To secure your instance for production, you should place TREK behind a TLS-terminating reverse proxy that handles SSL encryption while the app continues to listen on plain HTTP internally. This configuration is documented in the repository's wiki/Reverse-Proxy.md and ensures encrypted external traffic without modifying the application core.
Why TREK Requires a Reverse Proxy for SSL
TREK does not natively handle SSL termination. Instead, it expects to run behind a reverse proxy like Nginx that manages the TLS certificates and forwards decrypted requests. According to the source code in docker-compose.yml, the application listens on 0.0.0.0:3000 and relies on the X-Forwarded-Proto header to detect HTTPS connections.
Additionally, TREK uses a WebSocket endpoint at /ws for real-time sync. This requires specific Nginx directives to maintain long-lived connections, as implemented in the official configuration examples.
Prerequisites
Before configuring SSL for TREK, ensure you have:
- A running TREK instance on port 3000 (as defined in
Dockerfileanddocker-compose.yml) - Nginx installed on your server
- SSL certificates (e.g., from Let's Encrypt/Certbot) stored at paths like
/etc/ssl/fullchain.pemand/etc/ssl/privkey.pem - A domain name pointing to your server
Nginx Configuration for TREK SSL
The recommended configuration performs three critical tasks: redirecting HTTP to HTTPS, terminating TLS, and proxying WebSocket connections.
HTTP to HTTPS Redirect
Create a server block that listens on port 80 and redirects all traffic to HTTPS:
server {
listen 80;
server_name trek.yourdomain.com;
return 301 https://$host$request_uri;
}
HTTPS Server Block with SSL Certificates
Configure the main SSL server block that terminates TLS and proxies to TREK:
server {
listen 443 ssl http2;
server_name trek.yourdomain.com;
ssl_certificate /etc/ssl/fullchain.pem;
ssl_certificate_key /etc/ssl/privkey.pem;
client_max_body_size 500m;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
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;
}
}
WebSocket Support for Real-Time Collaboration
Add a specific location block for the /ws endpoint to handle WebSocket upgrades:
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_read_timeout 86400;
}
The proxy_read_timeout 86400 directive keeps socket connections open for up to 24 hours, preventing idle timeouts on long-running collaboration sessions.
TREK Environment Variables
To ensure TREK correctly handles proxied requests, set these variables in your docker-compose.yml or container runtime:
environment:
- PORT=3000
- TRUST_PROXY=1
- FORCE_HTTPS=true
TRUST_PROXY=1 tells TREK to trust the X-Forwarded-Proto header from Nginx, which is essential for generating correct URLs in OIDC callbacks and email links. FORCE_HTTPS=true enables internal HTTPS redirects and secure cookies, but only use this when a TLS-terminating proxy is present to avoid redirect loops.
Source File Reference
The following files in the mauriceboe/TREK repository contain the official configuration details:
wiki/Reverse-Proxy.md— Complete reverse-proxy guide with Nginx and Caddy examplesdocker-compose.yml— Production compose file showingTRUST_PROXYandFORCE_HTTPSflagsREADME.md— Overview of reverse proxy requirements in the Reverse Proxy sectionDockerfile— Container configuration confirming the app listens on0.0.0.0:3000
Summary
- TREK runs on port 3000 and requires a TLS-terminating reverse proxy for production SSL
- Configure Nginx to redirect HTTP to HTTPS, terminate SSL on port 443, and proxy to
localhost:3000 - Add specific WebSocket handling for
/wswithUpgradeheaders and extended timeouts - Set
TRUST_PROXY=1and optionallyFORCE_HTTPS=truein your environment variables - Reference
wiki/Reverse-Proxy.mdfor official examples anddocker-compose.ymlfor production settings
Frequently Asked Questions
Does TREK support native SSL without a reverse proxy?
No. According to the repository's README.md and Dockerfile, TREK listens on plain HTTP and expects SSL termination to occur at the reverse proxy layer. This architecture keeps the application simple and allows the proxy to handle certificate management and security protocols.
Why is my WebSocket connection dropping after 60 seconds?
Nginx's default proxy_read_timeout is 60 seconds. For TREK's real-time collaboration features, you must increase this value—typically to 86400 (24 hours)—in the /ws location block. This prevents idle timeouts on long-lived socket connections used for real-time sync.
What is the difference between TRUST_PROXY and FORCE_HTTPS?
TRUST_PROXY tells TREK to trust the X-Forwarded-Proto header from Nginx, allowing it to detect HTTPS correctly and generate proper callback URLs. FORCE_HTTPS makes TREK issue its own 301 redirects, HSTS headers, and secure cookies. Only enable FORCE_HTTPS when you have a working TLS-terminating proxy, otherwise you may cause redirect loops or broken connections.
How do I handle large file uploads through Nginx?
Set client_max_body_size 500m in your Nginx server block to match TREK's backend limits for backup and restore operations. This corresponds to the upload limits documented in the repository's configuration files and prevents 413 Entity Too Large errors during backup restores.
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 →