Skip to content

NGINX as Webserver

New to NGINX? Start by reading NGINX introduction.

Notes

  • webserver is something that serves static contents (HTML, media, etc.)

  • NGINX was primarily introduced as a webserver

  • NGINX can server from different locations and in different ports at the same time

  • default site is at /etc/nginx/site-available/default but inferring from the previous point, we can add multiple site configuration files at /etc/nginx/sites-available each serving on different ports or even different domains such as:

    /etc/nginx/sites-available/
    ├── default
    ├── example.com
    └── mysite.com
  • /etc/nginx/sites-available just makes site available but not ready to serve, for the site be ready to serve, there should be symlink at /etc/nginx/sites-enabled of each site which is ready to serve content:

    sudo ln -s /etc/nginx/sites-available/mysite.com /etc/nginx/sites-enabled/

    which will create a symblink as such:

    lrwxrwxrwx 1 root root 37 Oct  7 11:52 /etc/nginx/sites-enabled/mysite.com -> /etc/nginx/sites-available/mysite.com

    Why Symlink?

    • changes made to /etc/nginx/sites-available/mysite.com are directly reflected on /etc/nginx/sites-enabled/mysite.com
    • symlink is just a pointer which means it saves storage
  • generally in production, there will mostly be only one webserver with a single domain but multi server architecture helps easy develop and test sites/apps

Serving Static Content

  1. The general flow is by start adding config file at /etc/nginx/sites-available/ and enabling by symlink at /etc/nginx/sites-enabled/ when ready. So, first:

    sudo mkdir /etc/nginx/sites-available/mysite.com
  2. The most basic skeleton to write configuration for NGINX webserver is:

    http {
        server {
            location / {
    
            }
        }
    }

    However http block can be omitted and just server {} is fine too.

  3. Add simple root directive to location block directive:

    location / {
        root /data/www;
    }

    When requests comes at mysite.com/ or mysite.com, serve from /data/www.

  4. This means data/www should exist and the default HTML file i.e. index.html file should exist there to start serving at /:

    sudo mkdir -p /data/www/
    echo "HI from mysite.com" | sudo tee /data/www/mysite.com
    sudo chown -R www-data:www-data /data/www/

    Changing owner is not mandatory (because NGINX is started as sudo nginx) but a good pratice because generally NGINX user and group is www-data and not root.

  5. Add more location directive if necessary, for example to serve /images from another location such as /media/images/:

    location /images/ {
        root /media/images/;
    }

    When requests comes at mysite.com/images/picture.png, return the image from /media/images/picture.png if available.

  6. Specify listening address:port inside the server block (generally the first line). This is necessary because default site is already using default port 80:

    http {
        server {
            listen 8090;
            ...
        }
    }

    Here address part is omitted so universal address 0.0.0.0 is applied.

  7. [Optional] Seperating access.log and error.log for this site only is also a good idea:

    http {
        server {
            ...
            access_log /var/log/nginx/mysite.com/access.log;
            error_log /var/log/nginx/mysite.com/error.log;
        }
    }

    These file should exist before nginx is started, so the same idea goes here:

    sudo mkdir /var/log/nginx/mysite.com/
    sudo touch /var/log/nginx/mysite.com/{access,error}.log
    sudo chown -R www-data:adm /var/log/nginx/mysite.com/

    Why www-data:adm? Because it is common practice for log files.

  8. Create symlink of mysite.com in /etc/nginx/sites-enabled:

    sudo ln -s /etc/nginx/sites-available/mysite.com /etc/nginx/sites-enabled/
  9. Validate and start serving:

    sudo nginx -t && sudo nginx
  10. Access your site:

    curl localhost:8090

    should return:

    HI from mysite.com

    Because the site is accessed, now /var/log/nginx/mysite.com/access.log does have some access logs, see it yourself.

Important Notes

  • naming mysite.com doesn’t mean NGINX server is allowed to serve as mysite.com
  • if you want to serve as mysite.com publicly, you should own the domain in order to serve as mysite.com becuase you need to set A or CNAME DNS records (from the domain name provider console such as: cloudflare or godaddy) to map mysite.com to your public IP address
  • continuing to previous point, you should also set server_name directive as mysite.com inside server {} block -> this only solves serving as http://mysite.com
  • to serve HTTPS, you need to have TLS certificate which is signed by trusted CA and mention it in NGINX configuration (ssl directive)

Important

Everything mentioned on important notes is not necessary for private site (not served publicly) because:

  1. You can easily change A record of DNS server you own so that mysite.com point to the webserver IP address.
  2. Even if HTTPS required, you can self signed TLS cert with openssl -> game over.
Last updated on