From f2283b480110da6af18121f601fd40275f3bc057 Mon Sep 17 00:00:00 2001 From: Chris Veleris Date: Tue, 10 Feb 2026 20:21:59 +0200 Subject: [PATCH] Setup infra for reverse proxy --- Dockerfile | 1 + README.md | 18 ++++++++++++++++++ backend/.env.example | 2 ++ backend/app.js | 4 ++++ backend/config/config.js | 10 ++++++++++ docker-compose.yml | 1 + 6 files changed, 36 insertions(+) diff --git a/Dockerfile b/Dockerfile index 8e63d3c33..7b439fea7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -122,6 +122,7 @@ ENV NODE_ENV=production \ TUDUDI_SESSION_SECRET="" \ TUDUDI_USER_EMAIL="" \ TUDUDI_USER_PASSWORD="" \ + TUDUDI_TRUST_PROXY=false \ DISABLE_TELEGRAM=false \ DISABLE_SCHEDULER=false \ TUDUDI_UPLOAD_PATH="/app/backend/uploads" \ diff --git a/README.md b/README.md index 1dcd1230c..4749b2029 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,24 @@ docker run \ Navigate to [http://localhost:3002](http://localhost:3002) and login with your credentials. +### Reverse Proxy Setup + +When running behind a reverse proxy (Caddy, Nginx, Traefik, etc.), set `TUDUDI_TRUST_PROXY` so that Express correctly reads client IPs from `X-Forwarded-For` headers. Without this, `express-rate-limit` will log a validation error. + +```bash +docker run \ + -e TUDUDI_TRUST_PROXY=true \ + -e TUDUDI_ALLOWED_ORIGINS=https://your-domain.com \ + ... +``` + +| Value | Meaning | +|-------|---------| +| `true` | Trust all proxies (simplest option for single-proxy setups) | +| `1` | Trust the first hop only | +| `loopback` | Trust loopback addresses (127.0.0.1/::1) | +| `172.16.0.0/12` | Trust a specific subnet | + ### 📚 Documentation For detailed setup instructions, configuration options, and getting started guides, visit: diff --git a/backend/.env.example b/backend/.env.example index e8986a1c0..3e45fe68a 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -26,3 +26,5 @@ REGISTRATION_TOKEN_EXPIRY_HOURS=24 DISABLE_SCHEDULER=false DISABLE_TELEGRAM=false + +# TUDUDI_TRUST_PROXY=true diff --git a/backend/app.js b/backend/app.js index 8b5cf3dbc..3900899f7 100644 --- a/backend/app.js +++ b/backend/app.js @@ -19,6 +19,10 @@ const API_BASE_PATH = `/api/${API_VERSION}`; const app = express(); +if (config.trustProxy !== false) { + app.set('trust proxy', config.trustProxy); +} + // Session store const sessionStore = new SequelizeStore({ db: sequelize, diff --git a/backend/config/config.js b/backend/config/config.js index aa563d00b..940366c1d 100644 --- a/backend/config/config.js +++ b/backend/config/config.js @@ -108,6 +108,16 @@ const config = { enabled: process.env.SWAGGER_ENABLED !== 'false', }, + trustProxy: (() => { + const val = process.env.TUDUDI_TRUST_PROXY; + if (val === undefined || val === '') return false; + if (val === 'true') return true; + if (val === 'false') return false; + const num = Number(val); + if (!isNaN(num) && val.trim() !== '') return num; + return val; + })(), + // Rate limiting configuration rateLimiting: { // Disable rate limiting in test environment diff --git a/docker-compose.yml b/docker-compose.yml index 9ff6600d3..1ba3ec1af 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,6 +7,7 @@ services: - TUDUDI_USER_PASSWORD=your-secure-password - TUDUDI_SESSION_SECRET=changeme-please-use-openssl - TUDUDI_ALLOWED_ORIGINS=http://localhost:3002 + - TUDUDI_TRUST_PROXY=false - TUDUDI_UPLOAD_PATH=/app/backend/uploads # Runtime UID/GID configuration - set these to match your host user/group - PUID=1001