Nginx - "The open source web server that powers 400 million websites"

Most people starting out in web development will use a development framework that has it's own built in web-server.

  • Meteor
  • Express.js
  • Ruby on Rails
  • Go application
  • Laravel PHP

The web-server will run on a specific port. 3000, 8081, 8000, 4000, 5000 are some usual default values, and will work with that locally on their laptops whilst building out their web app and testing it.

To then get the web-server to serve incoming traffic publicly via a URL in your browser, developers will set the port to 80 or 443 directly in their app to handle people visiting their web application. http://mysite.com or https://mysite.com

The main issue happens when new developers without major experience actually want to deploy their application in the Cloud and available publicly. If they are using AWS, Azure, Digital Ocean or similar, they will spin up a new instance or droplet with Ubuntu 16.04 or equivalent and using github will download their code to the new instance, install their web-app dependencies (e.g. npm install) and start their application like they would locally.

To setup HTTPS using their own application's webserver can sometimes be a little tricky, require some refactoring of code and handling of things like www re-writes.

We can avoid all of this by running the app like we would locally on our machines. i.e. running on port 5000 for a python-flask app. And then use Nginx the world's most powerful and most popular webserver in-front of it to handle the public requests (on port 80 - http and port 443 -https) and proxy them to the web-application.

This is one of the most common ways to use nginx. As a reverse-proxy.

Major benefits for doing it this way:

  • Nginx already comes pre-installed with almost all Cloud instances that you spin up. i.e. zero setup required
  • More standardized way of deploying your applications (even if they are very different frameworks or programming languages).
  • HTTPS (SSL) can be configured automatically with free SSL certificates using certbot!
  • Run multiple applications on the same server with ease! e.g. blog.mysite.com, mysite.com, slack.mysite.com

Ok. Let's get started with Nginx

Let's assume you have spun up your server, got your application running locally, and it is serving on port 3000.

Inside your Linux server command-line at the root directory:

> cd /etc/nginx/sites-available/

create a conf file: nginx-example.conf

> touch nginx-example.conf

and add basic nginx code block to handle http traffic:
> nano nginx-example.conf

add this code to the file and save it

   server {
   
      listen 80;

      server_name nakedbrigade.com
      root /node-weather-app;

      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:3000;
      }

      location ~ /.well-known {
          allow all;
      }

      client_max_body_size 50m;
  }

Restart the nginx service.
> sudo service nginx restart

Now traffic coming to your instance IP address with the http://mysite.com url in the request will be directed by nginx to use your web-application.


Setup SSL Certs for your application/website.

Now you have your website/web-app running using Nginx as a reverse proxy.

Let's setup free SSL certs to secure your site with HTTPS.

Install certbot on your machine (usually does not come pre-installed on Linux machines)

Copy and paste these commands one by one and execute to install certbot from the aptitude repo:

$ sudo apt-get update
$ sudo apt-get install software-properties-common
$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt-get update
$ sudo apt-get install python-certbot-nginx

Once you have installed certbot. Run this command to start your SSL provisioning and auto-setup on your Nginx.

$ sudo certbot --nginx

You will then get step by step instructions to generate install your Let's Encrypt certs.

Once the step-by-step guide finishes you can (if you want), recheck your /etc/nginx/sites-availabe/ directory and likely you'll notice a new nginx config file created to handle your SSL certs.

Automatically created by certbot:

server {

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

    server_name nakedbrigade.com;
    root /node-weather-app;

    ssl_certificate /etc/letsencrypt/live/nakedbrigade.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/nakedbrigade.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    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:3000;
    }

    location ~ /.well-known {
        allow all;
    }

    client_max_body_size 50m;
}

Restart the nginx service.
> sudo service nginx restart

Now traffic coming to your instance IP address with the secure SSL encrypted https://mysite.com url in the request will be directed by nginx to use your web-application.

Congratulations! You've just setup SSL certs on your site with no additional config on your application's webserver. Thanks to nginx and certbot!


What else can Nginx do?

Nginx is one powerful piece of software. Written in C and launched in 2004. It can do many other things including:

  • Use as your web-server on it's own. Or with OpenResty as a full web framework.
  • Use as a Load balancer between multiple servers.
  • Use as a caching layer, to serve cached content to your users.
  • Use as a Web Application Firewall (WAF) to secure your application.

Keep on Learning!