How To: Let's Encrypt and NodeBB

  • Let's Encrypt and NodeBB


    NodeBB is a special beast. One that takes careful grooming and maintenance. Ah, gone are the golden days of LAMP. That glorious "P", so easy to use but oh so poor on performance. With Node.js and living behind your webserver you no longer have the easy liberty of throwing down files and opening directory access any where you would like. What's that? You have to shutdown your NodeBB just to renew your Let's Encrypt SSL certificates? You are using SSL right? Shame, shame if you are not.

    Take notice! You no longer need to shutdown your webserver and NodeBB just to renew those Let's Encrypt certificates if you make a simple change to your webserver configuration.

    Back story

    Let's Encrypt is a free SSL certificate authority. You run their software on your server that authenticates with their master control. The key is proving that you have rights to the domain you are requesting a certificate for. Their software is a webserver so you can't already be running one on port 80. Theirs needs to bind to that port. To run their software, to renew my certificate, I have had to shutdown my webserver (which makes my NodeBB forum unavailable). It doesn't take long but I was annoyed that my NodeBB forum would have to be offline during that time. I knew there must be a solution to this problem and there is in their "webroot" option.

    The webroot flag keeps their software from needing to run as a webserver and just places special authentication files in your already existing webserver's html path. That is all fine-and-dandy for a typical LAMP setup but doesn't behave as well with Node.js, and NodeBB. It can behave though if you tell your webserver to exclude the super secret Let's Encrypt webroot path from going to NodeBB and point off somewhere else.


    We must tell the webserver that the .well-known/acme-challenge directory is not to be proxied off to like it needs to be for NodeBB.


    These configurations need to be in the unencrypted (port 80) section of your webserver configuration.

    Change with your actual domain name.

    server {
        listen       80;
        root   /var/www/;

    Add a location block for the Let's Encrypt directory

    location /.well-known/acme-challenge/  {
        try_files $uri =404;

    Bonus: If you want to only serve https traffic for your NodeBB forum make your root location block something like this

    location / {
        rewrite ^(.*)$1 permanent;

    Reload Nginx for the changes to take affect.

    sudo systemctl reload nginx

    Apache (and others)

    You will need to research how to setup the proper exclusion of the .well-known/acme-challenge directory from being proxied to

    Let's Encrypt


    When it is time to renew your certificate (or create your certificate) you would run the following command.

    Change with your actual domain name.

    sudo ./letsencrypt-auto certonly --webroot -w /var/www/ -d -d
    • certonly means to only have the certificates generated and do not try to modify any webserver (Nginx) configuration files. That task is left to the student (you).
    • --webroot tells Let's Encrypt to not run as a webserver and not to bind to port 80
    • -w points to the actual path on disk that Nginx can serve files from. This is the place that the .well-known/acme-challenge directory will be created in and inside of that directory Let's Encrypt will place temporary authorization files
    • -d the domain name that this certificate will authenticate for. Add additional -d flags for each of the names you may have.

    Windows (and others)

    You will need to research the syntax to execute the letsencrypt-auto command but the flags should be very similar to the Linux ones shown above.


    Symbolic Links

    It has been reported that symbolic links do not work well with the Let's Encrypt software. Therefore please avoid attempting to sym link the .well-known/acme-challenge directory to another location on your file system.


    What I have left out is the initial configuration of your webserver to accept SSL connections. There are numerous documents online to help with that portion. If it is done correctly for Let's Encrypt the certificate path will point to a live directory. Renewing the certificates only updates the files in the live directory and your webserver configuration is not touched.

    With this configuration I am able to run the command to update my certificates without having to shutdown my webserver thus making NodeBB unreachable from my webserver proxy.

    Contact me

  • @rod Details like this is helpful for someone like me. Will have to give this a try. Thanks!

  • I already covered this in my "High performance stack" tutorial. Still a nice tutorial.

  • @AOKP I just looked at your high performance tutorial. Definitely a lot of information. Possibly too much all at once. I think people may find this succinct post just related to Let's Encrypt easier to digest.

  • Edited to include a warning about using a sym link to the .well-known/acme-challenge directory.

  • Community Rep

    @rod, is the root you specify in the nginx config arbitrary, an empty directory path that actually exists, or does it need to be the actual root of the public folder? I have a non-standard configuration where I have a dedicated user for running NodeBB, and the actual root location is in the home folder of that user (which is also non-standard, in the /usr/share/nginx dir)

    EDIT: nvm, I forgot to specify the folder to save the file in with the -w flag


  • Admin

    @Bri root /var/www/; this one?

    It's not used by NodeBB, only by Let's Encrypt.

    It will try to access the file located in /.well-known/acme-challenge/, and that is relative to the root as defined.

    For my Let's Encrypt setup, I instead use:

      location "/.well-known/acme-challenge" {
          root /usr/share/nginx/html;

    ... as that folder is served by nginx already, so less configuration 😄 (I modify my ./letsencrypt-auto command according as well, of course)

  • Community Rep

    Cool, didn't know that you could put the "root" inside the location block, thanks!


| |