Skip to content

Optimum config for NodeBB under NGINX

Performance
  • 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
  • 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.


  • 0 Votes
    1 Posts
    290 Views
    No one has replied
  • 13 Votes
    17 Posts
    477 Views

    @小城风雨多 I was a die-hard OnePlus user since the 6T, but my experience with the 9 series has left me extremely disappointed and I probably won’t go back now I have a Samsung S23+ which works perfectly.

  • Is nginx necessary to use?

    Moved Solved Hosting
    2
    1 Votes
    2 Posts
    140 Views

    @Panda said in Cloudflare bot fight mode and Google search:

    Basic question again, is nginx necessary to use?

    No, but you’d need something at least to handle the inbound requests, so you could use Apache, NGINX, Caddy… (there are plenty of them, but I tend to prefer NGINX)

    @Panda said in Cloudflare bot fight mode and Google search:

    Do these two sites need to be attached to different ports, and the ports put in the DNS record?

    No. They will both use ports 80 (HTTP) and 443 (HTTPS) by default.

    @Panda said in Cloudflare bot fight mode and Google search:

    Its not currently working, but how would the domain name know which of the two sites to resolve to without more info?
    Currently it only says the IP of the whole server.

    Yes, that’s correct. Domain routing is handled (for example) at the NGINX level, so whatever you have in DNS will be presented as the hostname, and NGINX will expect a match which once received, will then be forwarded onto the relevant destination.

    As an example, in your NGINX config, you could have (at a basic level used in reverse proxy mode - obviously, the IP addresses here are redacted and replaced with fakes). We assume you have created an A record in your DNS called “proxy” which resolves to 192.206.28.1, so fully qualified, will be proxy.sudonix.org in this case.

    The web browser requests this site, which is in turn received by NGINX and matches the below config

    server { server_name proxy.sudonix.org; listen 192.206.28.1; root /home/sudonix.org/domains/proxy.sudonix.org/ogproxy; index index.php index.htm index.html; access_log /var/log/virtualmin/proxy.sudonix.org_access_log; error_log /var/log/virtualmin/proxy.sudonix.org_error_log; location / { proxy_set_header Access-Control-Allow-Origin *; proxy_set_header Host $host; proxy_pass http://localhost:2000; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Api-Key $http_x_api_key; } location /images { index index.php index.htm index.html; root /home/sudonix.org/domains/proxy.sudonix.org/ogproxy; } fastcgi_split_path_info "^(.+\.php)(/.+)$"; listen 192.206.28.1:443 ssl http2; ssl_certificate /home/sudonix.org/domains/proxy.sudonix.org/ssl.combined; ssl_certificate_key /home/sudonix.org/ssl.key; }

    The important part here is server_name proxy.sudonix.org; as this is used to “map” the request to the actual domain name, which you can see in the root section as root /home/sudonix.org/domains/proxy.sudonix.org/ogproxy;

    As the DNS record you specified matches this hostname, NGINX then knows what to do with the request when it receives it.

  • SEO and Nodebb

    Performance
    2
    2 Votes
    2 Posts
    140 Views

    @Panda It’s the best it’s ever been to be honest. I’ve used a myriad of systems in the past - most notably, WordPress, and then Flarum (which for SEO, was absolutely dire - they never even had SEO out of the box, and relied on a third party extension to do it), and NodeBB easily fares the best - see below example

    https://www.google.com/search?q=site%3Asudonix.org&oq=site%3Asudonix.org&aqs=chrome..69i57j69i60j69i58j69i60l2.9039j0j3&sourceid=chrome&ie=UTF-8#ip=1

    However, this was not without significant effort on my part once I’d migrated from COM to ORG - see below posts

    https://community.nodebb.org/topic/17286/google-crawl-error-after-site-migration/17?_=1688461250365

    And also

    https://support.google.com/webmasters/thread/221027803?hl=en&msgid=221464164

    It was painful to say the least - as it turns out, there was an issue in NodeBB core that prevented spiders from getting to content, which as far as I understand, is now fixed. SEO in itself is a dark art - a black box that nobody really fully understands, and it’s essentially going to boil down to one thing - “content”.

    Google’s algorithm for indexing has also changed dramatically over the years. They only now crawl content that has value, so if it believes that your site has nothing to offer, it will simply skip it.

  • 11 Votes
    47 Posts
    3k Views

    @DownPW Seems fine.

  • 0 Votes
    2 Posts
    151 Views

    @eeeee they are nothing to worry about, and can be ignored.

  • 14 Votes
    69 Posts
    5k Views

    @phenomlab

    Seems to be better with some scaling fix for redis on redis.conf. I haven’t seen the message yet since the changes I made

    # I increase it to the value of /proc/sys/net/core/somaxconn tcp-backlog 4096 # I'm uncommenting because it can slow down Redis. Uncommented by default !!!!!!!!!!!!!!!!!!! #save 900 1 #save 300 10 #save 60 10000

    If you have other Redis optimizations. I take all your advice

    https://severalnines.com/blog/performance-tuning-redis/

  • NodeBB 1.19.3

    Solved Performance
    33
    4 Votes
    33 Posts
    3k 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

    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