Essential Proxy Header Directives and Port Mappings for NodeBB on NGINX

Running a self-hosted community with modern, real-time messaging requires coordinating an internal web application with a hardened public reverse proxy. By default, NodeBB operates on internal network ports that should not be accessed directly by forum visitors over standard browsing sessions. Configuring an upstream reverse proxy allows community owners to route public traffic cleanly to the backend application, terminate secure connections, and maintain persistent WebSocket sessions required for live topic updates and notifications.
Port 4567: The Default Upstream Application Target
By default, NodeBB starts its internal listeners on port 4567. When accessed without an intermediate web server, instances require forum members to enter this port directly within the URL, such as http://example.org:4567. To eliminate non-standard port numbers from forum links, NGINX is configured to intercept standard requests on public addresses and proxy them internally.
According to the official NginX - NodeBB Documentation, the standard proxy_pass destination for an instance located on the same physical operating system is http://127.0.0.1:4567. In nearly every standard configuration, this proxy_pass directive should never include a trailing slash or path suffix. If the forum is deployed to an intentional subdirectory, such as /forum, the location block must declare location /forum/ while keeping the downstream proxy_pass cleanly directed to http://127.0.0.1:4567 without appending the subfolder path.
HTTP 1.1 and Essential Socket.IO Upgrade Headers
NodeBB relies heavily on real-time event distribution through Socket.IO. Standard reverse proxy configurations that only support basic HTTP protocols will sever these interactive channels, causing interface lag or outright connection dropouts. Establishing persistent WebSocket handshakes requires forcing the proxy protocol to HTTP version 1.1 alongside explicit connection upgrade instructions.
A functional NodeBB proxy location block requires specific forwarding headers to ensure user IP tracking and state management function properly across internal boundaries:
proxy_set_header X-Real-IP $remote_addr;— passes the actual client IP address directly to the forum software rather than logging the local loopback address.proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;— appends client proxy chain information to assist in logging and IP-based moderation tools.proxy_set_header X-Forwarded-Proto $scheme;— informs NodeBB whether the external request originated over an unencrypted or secure transport layer.proxy_set_header Host $http_host;— preserves the original domain requested by the user browser.proxy_set_header X-NginX-Proxy true;— signals upstream handlers that traffic has crossed an NGINX proxy boundary.proxy_redirect off;— suppresses NGINX rewrite modifications on outbound redirect headers sent by the NodeBB application.proxy_http_version 1.1;— mandates HTTP 1.1 compliance, which is necessary for protocol elevation.proxy_set_header Upgrade $http_upgrade;— forwards client upgrade headers to initiate WebSocket communication.proxy_set_header Connection "upgrade";— maintains the active socket connection for Socket.IO event streams.
Administrators reviewing software architectures in our NodeBB At-a-Glance: Real-Time Forum Software Profile will recognize that omitting the WebSocket upgrade directives disables real-time forum notifications and live typing indicators.
Ports 4567 and 4568: Multi-Port Upstream Clustering
As discussion volume grows, community hosts frequently scale backend processes across multiple CPU threads. When running multi-process NodeBB deployments, the forum's internal config.json file configures port listeners across an array, assigning multiple listening ports such as ["4567","4568"].
To distribute traffic evenly between these separate internal threads, NGINX uses an upstream group defined in the configuration hierarchy:
upstream io_nodes {
ip_hash;
server 127.0.0.1:4567;
server 127.0.0.1:4568;
}
In this clustered configuration, the primary location block adjusts its target directive to proxy_pass http://io_nodes;. The ip_hash; balancing directive ensures that individual client sessions consistently map to the same backend NodeBB process, preventing broken WebSocket handshakes during active conversations.
Ports 80 and 443: Public Routing and Secure Edge Delivery
Public web traffic enters through standard system ports: port 80 for plaintext HTTP requests and port 443 for encrypted connections. When deploying HTTPS, port 80 functions primarily as a redirection gateway. The NGINX server block listens on port 80 and immediately returns an HTTP 302 redirection to secure URLs using return 302 https://$server_name$request_uri;.
The companion server block listens on port 443 with SSL enabled. Inside this secure block, administrators define certificates, private keys, and protocol guardrails. The NodeBB proxy guide specifies configuring ssl_protocols TLSv1 TLSv1.1 TLSv1.2; while avoiding weak legacy options like SSLv2 and SSLv3. It also applies cipher restrictions such as AES128+EECDH:AES128+EDH with ssl_prefer_server_ciphers on;. Sysadmins exploring proxy mechanics can review our NGINX Open Source Profile: Codebase Health and Proxy Architecture for additional context on server block structure.
Status 502: Troubleshooting Gateways and Custom Offline Pages
When an internal NodeBB instance stops or restarts, NGINX cannot complete requests to port 4567, resulting in an HTTP 502 Bad Gateway response. On CentOS 7 distributions, administrators may encounter 502 errors even when NodeBB is active; this issue is resolved by running setsebool -P httpd_can_network_connect on to grant proxy network access through SELinux policies.
To avoid displaying standard browser error pages during maintenance windows, NGINX can serve a custom page. Administrators create a static file named 502.html inside /usr/share/nginx/html, which serves as the default document root. The active server block then declares error_page 502 /502.html; alongside an internal location directive:
location = /502.html {
root /usr/share/nginx/html;
internal;
}
Applying these directives requires saving the file in /path/to/nginx/sites-available/* (aliased to ../sites-enabled), /path/to/nginx/conf.d/*.conf, or /etc/nginx/sites-available/default. Executing sudo service nginx restart applies the changes, ensuring smooth failover whenever internal application sockets recycle.
Sources
Published October 30, 2026. No affiliate links on this page. Facts come from the sources linked above; check them for updates.