Nginx For JS Devs

Posted: September 3, 2021 Category: backendTagged: nginxreverse proxy

Benefits of nginx

  • reverse proxying, including binding to port 80 so that clients don’t have to think about your cutesy lil port numbers
  • delegate serving of static files
  • apply https to an endpoint
  • load balance

… in other words, things that don’t often come up till you have to deploy.

General installation & usage as a regular service

  • sudo apt-get install nginx
  • sudo service nginx start. You won’t see any output, so:
  • sudo service nginx status to verify that it’s running ok
  • sudo service nginx stop to stop.

Modify config

So the full config is a file with this outline, per this handy SO answer:

events {
  ...
}
http {
  ...
  server {
      ...
  }
}

But what generally happens is that the nginx files are merged from fragments of config info across lots of different files. If installed locally, you can basically just:

  • Modify the server.location block in the default configuration, usually at /etc/nginx/sites-available/default
  • (don’t forget to change the location directive’s / route shown below to whatever else makes sense in your scenario).

A generalised example config:

server {
  location / {
    # ######## EXAMPLE TEMPLATE. COPY AND MODIFY/DELETE SECTIONS AS NEEDED #############
    # if not listening on default port 80 for some reason:
    listen nnnn; # where nnnn is the port number

    # if your server has a name, eg:
    server_name my.example.com

    # if proxying everything, eg:
    proxy_pass http://localhost:3000;

    # but if proxying static files only, you may as well
    # 1) sit the server right inside the intended folder for static assets:
    root /eg/path/to/public;
    # and/or 2) you probably need to change the route on this whole location {} block to "location /static {...}" or similar...

    # attempt to serve incoming requests as file uris; failing that,
    # as directories; failing that, you usually want to hand the request over to the
    # proxied endpoint to deal with it:
    try_files $uri $uri/ @appserver;

    # if there's a static index file and nginx
    # is responsible for serving it:
    index index.html;

    # u might also want additional proxy settings to enforce newer http protocol:
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;

    # (if modifying /etc/nginx/sites-available/default,
    # there were likely other settings in here; u can leave them
    # alone)...
    ...
  }
  
  # if you've decided to reference '@appserver' or whatever
  # as illustrated above in the above block, you'd need to also go ahead and define it, eg:
  location @appserver {
      proxy_pass http://localhost:3000;
  }
}
  • save, restart nginx after your edits: sudo service nginx restart
  • the app (in this example) should be available at ‘localhost’ now.

Running as a Dockerized Instance

I was following a tutorial using the nginxinc/nginx-unprivileged:1-alpine image and did not have to supply a whole config: only the /etc/nginx/conf.d/default.conf file needed to be supplied, with basically the exact same contents as the example given above.

testing in your dev sandbox

I found it easiest to run the dockerized version; I actually could not get the standalone install to work properly under WSL2. If you’re using the standalone version and want quicker-n-dirtier start/stops for testing (use which nginx to find the exact path for invocation):

# start
/usr/sbin/nginx -c /path/to/conf

# stop
kill -3 $(cat /usr/sbin/nginx/logs/nginx.pid)

For the docker version i just relied on docker-compose to stand up / tear down my network with proxy, app and db servers. Happy proxying!