Simple Guide to Setting Up an NGINX Reserve Proxy

I will first highly recommend to read Installing the NGINX Web Server on Debian & Ubuntu and Installing LetsEncrypt's CertBot Package on Debian & Ubuntu articles if you do not already have NGINX and using LetsEncrypt installed and configured.

Creating the Configuration File

First, we are going to create the NGINX configuration file for your first website you want to run using Ghost Blog as our example web application of choice. Make sure to change coderoasis.conf to your own domain that you want to use.

sudo nano /etc/nginx/sites-available/coderoasis.conf

The following is a generalized configuration file that is a bare minimal setup for running Ghost as your web application of choice. The first server block sets up our redirection to the https:// version of our domain and does a 301 permanent redirection for all incoming traffic. We also chosen to listen on IPv4 and IPv6.

server {

        listen 80;
        listen [::]:80;

        # Redirection Configuration
        server_name coderoasis.com;
        return 301 https://coderoasis.com;

}

SSL Configuration


Next we will open up a second server block like the following. It is for all traffic that is going to be connecting via our SSL or https://` connection once the redirect has been performed.

server {

        listen 443 http2 ssl;
        listen [::]:443 http2 ssl;

Next, in my configuration files once we setup the listening ports, I like to do the SSL configuration. This is where our LetsEncrypt certificates come into place. The options-ssl-nginx.conf; is recommended SSL security settings that make our site a little more secure by default. Finally, the LetsEncrypt generates us a Diffie-Hellman (DH) parameters file which is ssl-dhparams.pem in our SSL configuration.

It enhances the security of Perfect Forward Secrecy (PFS) in SSL/TLS by explicitly providing strong DH parameters instead of relying on weak, default ones. These parameters are used in the Diffie-Hellman key exchange algorithm to negotiate a secure session key between the server and client.

        # SSL Configuration
        ssl_certificate /etc/letsencrypt/live/coderoasis.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/coderoasis.com/privkey.pem;
        include /etc/letsencrypt/options-ssl-nginx.conf;
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

General Configuration

Now we have the General Settings part of our website configuration It sets our server_name, root directory, index, and other settings as needed. Since we are proxying Ghost Blog, we can comment out the root and index lines. The final two lines deals with uploading files like themes or pictures you can use with the blog. By default, we allow 100MB files and 3 minutes for the upload to complete. You can adjust these as needed, but the ones we use here are recommended.

        # General Configuration
        server_name coderoasis.com;
        #root /var/www/html;
        #index index.php index.html;
        client_max_body_size 100m;
        client_body_timeout 120s;

Reverse Proxy Configuration

The final part of our configuration file is for the / or root of where the site is going to be installed. Here at CoderOasis, we have the blog installed on the main domain, https://coderoasis.com/. You could even do a sub-domain like blog.coderoasis.com if you prefer for your own site. The choice is yours at the end of the day.

The location block tells the webserver to run the application in the root folder of /. You could also make it a dub-directory such as /blog/ if you wanted too. These headers ensure your backend app receives correct information about the original client request (IP, Protocol, and Domain), which is essential for accurate behavior and logging behind a reverse proxy.

        # Ghost Blog
        location / {
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header Host $http_host;
                proxy_pass http://127.0.0.1:2368;
        }
}

Checking Configuation

Finally, we want to run the following commands. The first one creates a symbolic link to sites-enabled directory for the site to be alive. The second line will check for any errors with your NGINX configuration. Then at last, we will reload NGINX for the changes to take effect. Please remember when you make any changes to any NGINX or site configuration files, you always need to reload NGINX for the changes you make to take effect.

sudo ln -s /etc/nginx/sites-available/coderoasis.conf /etc/nginx/sites-enabled/

sudo nginx -t

sudo systemctl reload nginx

The Conclusion

We have successfully created a default example of a configuration file for how an NGINX proxy works! Let's say you run another application, and it uses port 3001. You will change proxy_pass http://127.0.0.1:3001 for that application to run. Make sure to always double check the server_name and the SSL domain-name.com so they match where your website is actually installed.

Here is the full file so you can see all of it in a single go of how it is supped to look when you copy, edit the parts needed, and past it into your domain-name.conf file.

server {

        listen 80;
        listen [::]:80;

        # Redirection Configuration
        server_name coderoasis.com;
        return 301 https://coderoasis.com;

}

server {

        listen 443 http2 ssl;
        listen [::]:443 http2 ssl;

        # SSL Configuration
        ssl_certificate /etc/letsencrypt/live/coderoasis.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/coderoasis.com/privkey.pem;
        include /etc/letsencrypt/options-ssl-nginx.conf;
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

        # General Configuration
        server_name coderoasis.com;
        #root /var/www/html;
        #index index.php index.html;
        client_max_body_size 100m;
        client_body_timeout 120s;

        # Ghost Blog
        location / {
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header Host $http_host;
                proxy_pass http://127.0.0.1:2368;
        }

}