Skip to content

Optimum config for NodeBB under NGINX

Performance
4 2 1.6k 1
  • I noticed that my v3 instance of NodeBB in test was so much slower than live, but was using the same database etc. On closer inspection, the nginx configuration needed a tweak, so I’m posting my settings here so others can benefit from it. Note, that various aspects have been redacted for obvious privacy and security reasons, and to this end, you will need to substitute these values for those that exist in your own environment.

    server {
        # Ensure you put your server name here, such as example.com www.example.com etc.
    	server_name sservername;
    	listen x.x.x.x:443 ssl http2;
    	access_log /path/to/access.log;
    	error_log /path/to/error.log;
    
    	ssl_certificate /path/to/ssl.combined;
    	ssl_certificate_key /path/to/ssl.key;
        # You may not need the below values, so feel free to remove these if not required
    	rewrite ^\Q/mail/config-v1.1.xml\E(.*) $scheme://$host/cgi-bin/autoconfig.cgi$1 break;
    	rewrite ^\Q/.well-known/autoconfig/mail/config-v1.1.xml\E(.*) $scheme://$host/cgi-bin/autoconfig.cgi$1 break;
    	rewrite ^\Q/AutoDiscover/AutoDiscover.xml\E(.*) $scheme://$host/cgi-bin/autoconfig.cgi$1 break;
    	rewrite ^\Q/Autodiscover/Autodiscover.xml\E(.*) $scheme://$host/cgi-bin/autoconfig.cgi$1 break;
    	rewrite ^\Q/autodiscover/autodiscover.xml\E(.*) $scheme://$host/cgi-bin/autoconfig.cgi$1 break;
        # You may not need the above values, so feel free to remove these if not required
    
    	client_body_buffer_size 10K;
    	client_header_buffer_size 1k;
    	client_max_body_size 8m;
    	large_client_header_buffers 4 4k;
    
    	client_body_timeout 12;
    	client_header_timeout 12;
    	keepalive_timeout 15;
    	send_timeout 10;
    
    
        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;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_redirect off;
    
        # Socket.io Support
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    	gzip on;
    	gzip_disable "msie6";
    	gzip_vary on;
    	gzip_proxied any;
    	gzip_min_length 1024;
    	gzip_comp_level 6;
    	gzip_buffers 16 8k;
    	gzip_http_version 1.1;
    	gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
    
        add_header X-XSS-Protection "1; mode=block";
        add_header X-Download-Options "noopen" always;
        add_header Content-Security-Policy "upgrade-insecure-requests" always;
        add_header Referrer-Policy 'no-referrer' always;
        add_header Permissions-Policy "accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=()" always;
        # This is the string that will show in the headers if requested, so you can put what you want in here. Keep it clean :)
        add_header X-Powered-By "<whatever you want here>" always;
        add_header X-Permitted-Cross-Domain-Policies "none" always;
        location / {
        # Don't forget to change the port to the one you use. I have a non-standard one :)
        proxy_pass http://127.0.0.1:5000;
        }
    
        location @nodebb {
            # Don't forget to change the port to the one you use. I have a non-standard one :)
            proxy_pass http://127.0.0.1:5000;
        }
    
        location ~ ^/assets/(.*) {
            root /path/to/nodebb/;
            try_files /build/public/$1 /public/$1 @nodebb;
            add_header Cache-Control "max-age=31536000";
        }
    
        location /plugins/ {
            root /path/to/nodebb/build/public/;
            try_files $uri @nodebb;
            add_header Cache-Control "max-age=31536000";
        }
    
    	if ($scheme = http) {
            # Ensure you set your actual domain here
    		rewrite ^/(?!.well-known)(.*) https://yourdomain/$1 break;
    	}
    }
    
    

    I’ve added comments at the obvious places where you need to make changes. Depending on how your server is configured, and it’s capabilities, this should improve performance no end.

    There is a caveat though, and it’s an important one

    Don’t use insane levels in the below section

    	client_body_buffer_size 10K;
    	client_header_buffer_size 1k;
    	client_max_body_size 8m;
    	large_client_header_buffers 4 4k;
    
    	client_body_timeout 12;
    	client_header_timeout 12;
    	keepalive_timeout 15;
    	send_timeout 10;
    

    Keep to these values, and if anything, adjust them DOWN to suit your server.

  • I noticed that my v3 instance of NodeBB in test was so much slower than live, but was using the same database etc. On closer inspection, the nginx configuration needed a tweak, so I’m posting my settings here so others can benefit from it. Note, that various aspects have been redacted for obvious privacy and security reasons, and to this end, you will need to substitute these values for those that exist in your own environment.

    server {
        # Ensure you put your server name here, such as example.com www.example.com etc.
    	server_name sservername;
    	listen x.x.x.x:443 ssl http2;
    	access_log /path/to/access.log;
    	error_log /path/to/error.log;
    
    	ssl_certificate /path/to/ssl.combined;
    	ssl_certificate_key /path/to/ssl.key;
        # You may not need the below values, so feel free to remove these if not required
    	rewrite ^\Q/mail/config-v1.1.xml\E(.*) $scheme://$host/cgi-bin/autoconfig.cgi$1 break;
    	rewrite ^\Q/.well-known/autoconfig/mail/config-v1.1.xml\E(.*) $scheme://$host/cgi-bin/autoconfig.cgi$1 break;
    	rewrite ^\Q/AutoDiscover/AutoDiscover.xml\E(.*) $scheme://$host/cgi-bin/autoconfig.cgi$1 break;
    	rewrite ^\Q/Autodiscover/Autodiscover.xml\E(.*) $scheme://$host/cgi-bin/autoconfig.cgi$1 break;
    	rewrite ^\Q/autodiscover/autodiscover.xml\E(.*) $scheme://$host/cgi-bin/autoconfig.cgi$1 break;
        # You may not need the above values, so feel free to remove these if not required
    
    	client_body_buffer_size 10K;
    	client_header_buffer_size 1k;
    	client_max_body_size 8m;
    	large_client_header_buffers 4 4k;
    
    	client_body_timeout 12;
    	client_header_timeout 12;
    	keepalive_timeout 15;
    	send_timeout 10;
    
    
        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;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_redirect off;
    
        # Socket.io Support
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    	gzip on;
    	gzip_disable "msie6";
    	gzip_vary on;
    	gzip_proxied any;
    	gzip_min_length 1024;
    	gzip_comp_level 6;
    	gzip_buffers 16 8k;
    	gzip_http_version 1.1;
    	gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
    
        add_header X-XSS-Protection "1; mode=block";
        add_header X-Download-Options "noopen" always;
        add_header Content-Security-Policy "upgrade-insecure-requests" always;
        add_header Referrer-Policy 'no-referrer' always;
        add_header Permissions-Policy "accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=()" always;
        # This is the string that will show in the headers if requested, so you can put what you want in here. Keep it clean :)
        add_header X-Powered-By "<whatever you want here>" always;
        add_header X-Permitted-Cross-Domain-Policies "none" always;
        location / {
        # Don't forget to change the port to the one you use. I have a non-standard one :)
        proxy_pass http://127.0.0.1:5000;
        }
    
        location @nodebb {
            # Don't forget to change the port to the one you use. I have a non-standard one :)
            proxy_pass http://127.0.0.1:5000;
        }
    
        location ~ ^/assets/(.*) {
            root /path/to/nodebb/;
            try_files /build/public/$1 /public/$1 @nodebb;
            add_header Cache-Control "max-age=31536000";
        }
    
        location /plugins/ {
            root /path/to/nodebb/build/public/;
            try_files $uri @nodebb;
            add_header Cache-Control "max-age=31536000";
        }
    
    	if ($scheme = http) {
            # Ensure you set your actual domain here
    		rewrite ^/(?!.well-known)(.*) https://yourdomain/$1 break;
    	}
    }
    
    

    I’ve added comments at the obvious places where you need to make changes. Depending on how your server is configured, and it’s capabilities, this should improve performance no end.

    There is a caveat though, and it’s an important one

    Don’t use insane levels in the below section

    	client_body_buffer_size 10K;
    	client_header_buffer_size 1k;
    	client_max_body_size 8m;
    	large_client_header_buffers 4 4k;
    
    	client_body_timeout 12;
    	client_header_timeout 12;
    	keepalive_timeout 15;
    	send_timeout 10;
    

    Keep to these values, and if anything, adjust them DOWN to suit your server.

    Further configuration changes can be made to the nginx core itself, although my recommendation here is to leave this alone unless you are sure you know what you are doing.

    https://webdock.io/en/docs/webdock-control-panel/optimizing-performance/optimizing-nginx-high-traffic-websites

  • phenomlabundefined phenomlab marked this topic as a regular topic on
  • I noticed that my v3 instance of NodeBB in test was so much slower than live, but was using the same database etc. On closer inspection, the nginx configuration needed a tweak, so I’m posting my settings here so others can benefit from it. Note, that various aspects have been redacted for obvious privacy and security reasons, and to this end, you will need to substitute these values for those that exist in your own environment.

    server {
        # Ensure you put your server name here, such as example.com www.example.com etc.
    	server_name sservername;
    	listen x.x.x.x:443 ssl http2;
    	access_log /path/to/access.log;
    	error_log /path/to/error.log;
    
    	ssl_certificate /path/to/ssl.combined;
    	ssl_certificate_key /path/to/ssl.key;
        # You may not need the below values, so feel free to remove these if not required
    	rewrite ^\Q/mail/config-v1.1.xml\E(.*) $scheme://$host/cgi-bin/autoconfig.cgi$1 break;
    	rewrite ^\Q/.well-known/autoconfig/mail/config-v1.1.xml\E(.*) $scheme://$host/cgi-bin/autoconfig.cgi$1 break;
    	rewrite ^\Q/AutoDiscover/AutoDiscover.xml\E(.*) $scheme://$host/cgi-bin/autoconfig.cgi$1 break;
    	rewrite ^\Q/Autodiscover/Autodiscover.xml\E(.*) $scheme://$host/cgi-bin/autoconfig.cgi$1 break;
    	rewrite ^\Q/autodiscover/autodiscover.xml\E(.*) $scheme://$host/cgi-bin/autoconfig.cgi$1 break;
        # You may not need the above values, so feel free to remove these if not required
    
    	client_body_buffer_size 10K;
    	client_header_buffer_size 1k;
    	client_max_body_size 8m;
    	large_client_header_buffers 4 4k;
    
    	client_body_timeout 12;
    	client_header_timeout 12;
    	keepalive_timeout 15;
    	send_timeout 10;
    
    
        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;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_redirect off;
    
        # Socket.io Support
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    	gzip on;
    	gzip_disable "msie6";
    	gzip_vary on;
    	gzip_proxied any;
    	gzip_min_length 1024;
    	gzip_comp_level 6;
    	gzip_buffers 16 8k;
    	gzip_http_version 1.1;
    	gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
    
        add_header X-XSS-Protection "1; mode=block";
        add_header X-Download-Options "noopen" always;
        add_header Content-Security-Policy "upgrade-insecure-requests" always;
        add_header Referrer-Policy 'no-referrer' always;
        add_header Permissions-Policy "accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=()" always;
        # This is the string that will show in the headers if requested, so you can put what you want in here. Keep it clean :)
        add_header X-Powered-By "<whatever you want here>" always;
        add_header X-Permitted-Cross-Domain-Policies "none" always;
        location / {
        # Don't forget to change the port to the one you use. I have a non-standard one :)
        proxy_pass http://127.0.0.1:5000;
        }
    
        location @nodebb {
            # Don't forget to change the port to the one you use. I have a non-standard one :)
            proxy_pass http://127.0.0.1:5000;
        }
    
        location ~ ^/assets/(.*) {
            root /path/to/nodebb/;
            try_files /build/public/$1 /public/$1 @nodebb;
            add_header Cache-Control "max-age=31536000";
        }
    
        location /plugins/ {
            root /path/to/nodebb/build/public/;
            try_files $uri @nodebb;
            add_header Cache-Control "max-age=31536000";
        }
    
    	if ($scheme = http) {
            # Ensure you set your actual domain here
    		rewrite ^/(?!.well-known)(.*) https://yourdomain/$1 break;
    	}
    }
    
    

    I’ve added comments at the obvious places where you need to make changes. Depending on how your server is configured, and it’s capabilities, this should improve performance no end.

    There is a caveat though, and it’s an important one

    Don’t use insane levels in the below section

    	client_body_buffer_size 10K;
    	client_header_buffer_size 1k;
    	client_max_body_size 8m;
    	large_client_header_buffers 4 4k;
    
    	client_body_timeout 12;
    	client_header_timeout 12;
    	keepalive_timeout 15;
    	send_timeout 10;
    

    Keep to these values, and if anything, adjust them DOWN to suit your server.

    hi @phenomlab , is there any reason that you do not use 4567?

    Additionally, do you scale your forum up to 3 ports?

    https://docs.nodebb.org/configuring/scaling/

  • hi @phenomlab , is there any reason that you do not use 4567?

    Additionally, do you scale your forum up to 3 ports?

    https://docs.nodebb.org/configuring/scaling/

    @crazycells hi - no security reason, or anything specific in this case. However, the nginx.conf I posted was from my Dev environment which uses this port as a way of not interfering with production.

    And yes, I use clustering on this site with three instances.


Related Topics
  • 4 Votes
    3 Posts
    237 Views
    thanks @DownPW ! this is definitely very helpful.
  • What’s going on with NodeBB?

    Performance nodebb script die
    20
    5 Votes
    20 Posts
    1k Views
    @cagatay The most reliable way to upgrade Node.js on Ubuntu depends on how you originally installed it. Method 1: Using NVM (Recommended) If you already use Node Version Manager (NVM), upgrading is simple. NVM allows you to keep both versions and switch between them if needed. Install Node 22: nvm install 22 Switch to Node 22: nvm use 22 Set it as your default: nvm alias default 22 Verify the change: node -v Method 2: Using NodeSource (PPA) If you installed Node.js via apt using the NodeSource repository, you need to update the repository script to point to the new version. Remove the old NodeSource list (optional but cleaner): sudo rm /etc/apt/sources.list.d/nodesource.list Download and run the NodeSource setup script for Node 22: curl -fsSL [https://deb.nodesource.com/setup_22.x](https://deb.nodesource.com/setup_22.x) | sudo -E bash - Install/Upgrade Node.js: sudo apt-get install -y nodejs Verify the installation: node -v Method 3: Using the ‘n’ Package If you have npm installed, you can use the n interactive manager. Clear the npm cache: sudo npm cache clean -f Install the ‘n’ helper: sudo npm install -g n Install Node 22: sudo n 22 Update your shell: hash -r Troubleshooting Permission Denied: If you see permission errors using Method 2 or 3, ensure you are using sudo. Path Issues: If node -v still shows version 20 after upgrading via NVM, restart your terminal or run source ~/.bashrc. Conflicts: Avoid mixing these methods. If you switch from apt to nvm, it is best to sudo apt remove nodejs first to avoid path conflicts.
  • 3 Votes
    6 Posts
    2k Views
    @DownPW said in Nginx core developer quits project in security dispute, starts “freenginx” fork: Maybe virtualmin implement it in the future… I don’t think they will - my guess is that they will stick with the current branch of NGINX. I’ve not personally tested it, but the GIT page seems to be very active. This is equally impressive [image: 1714914575066-8ac0d197-68fa-4bd8-bfa3-87237bf8f1f4-image.png] I think the most impressive on here is the native support of HTTP 3
  • NodeBB socket with CloudFlare

    Solved Performance socket cloudflare nodebb
    24
    3 Votes
    24 Posts
    8k Views
    Solved. Tuto here and here
  • NodeBB v3 Chat Very Slow

    Moved Performance nodebb v3 nodebb chat
    47
    11 Votes
    47 Posts
    13k Views
    @DownPW Seems fine.
  • 6 Votes
    36 Posts
    8k Views
    @justoverclock said in Digitalocean step by step guide to nginx configuration: i’m learning And that’s the whole point of this site If you don’t learn anything, you gain nothing.
  • NodeBB 1.19.3

    Solved Performance nodebb 1.19.3 performance
    33
    4 Votes
    33 Posts
    10k Views
    @phenomlab I find the problem Mark The error message indicated this path : http://localhost:4567/assets/plugins/nodebb-plugin-emoji/emoji/styles.css?v=6983dobg16u I change the path url on config.json [image: 1645128773854-47bacc80-f141-41e4-a261-3f8d650cc6f6-image.png] And all it’s good Weird, I didn’t have to change that path before 1.19.3 But this does not prevent the problem from a clean install with Emoji Plugin EDIT: After test, that resolv the problem installation for 1.18.x but not for 1.19.x (I have other error message when I run ./nodebb Setup For resume: NodeJS 16_x with 1.18.x is ok
  • Digitalocean Ubuntu configuration

    Solved Linux
    33
    12 Votes
    33 Posts
    7k Views
    @phenomlab thank you! not me