These are some notes I made when working on a customisable Nginx (also I made some other examples ).
Nginx is many things, a super fast web server, a streaming server, a reverse proxy, load balancer, cache, and probably a lot more. Whats good about it?
Configuration is intuitive (based on C Structs )
It is asynchronous, so is highly performant with concurrent requests and has low memory usage.
Caching and video streaming are relatively easy to set up
Unlike Apache, you can't embed server side programming languages into Nginx. However, thats where the reverse proxy comes in (more later).
Installing Nginx
(The below is one way to install Nginx, but you are better off using docker tbh)
On a Mac you can install using homebrew brew install nginx
.
The default port has been set in /usr/local/etc/nginx/nginx.conf
to 8080
so that nginx can run without sudo.
By default nginx will load all files in /usr/local/etc/nginx/servers/
.
To have launchd
start nginx at login:
ln -sfv /usr/local/opt/nginx/*.plist ~/Library/LaunchAgents
Set logs: /var/log/nginx
Then to load nginx:
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.nginx.plist
Or, if you don't want/need launchctl, you can just run nginx
Take a look at the 'nginx.conf' file. There are four 'contexts' - main, server, upstream, and location. All of these contain 'directives' - instructions for Nginx.
Reverse proxy
A reverse proxy is a type of proxy server that retrieves resources on behalf of a client from one or more servers. These resources are then returned to the client as though they originated from the proxy server itself -
[Wikipedia](https://en.wikipedia.org/wiki/Reverse_proxy)
With Nginx being asynchronous and a reverse proxy you have to configure all requests for dynamic content to use the upstream module .
Say you have 2 node apps and a static site. You want to have endpoints like:
An API would be running on port 8000 for example, and the admin section on port 8080. We would set them up as upstream in our nginx.conf file:
upstream api {
server localhost:8000;
}
upstream admin {
server localhost:8080;
}
server {
location /api {
proxy_pass http://api ;
}
location /admin {
proxy_pass http://admin ;
}
}
Directives
Contexts/block directives are a bit like scope, server {}
is a context.
Directives are key/value pairs like listen: 80;
server {
listen: 80;
root: '/path/to/your/sites';
index: index.html;
server: yourdomain.com;
location / {
default-type: 'text/html';
}
}
Standard directive - Set a value. Can only be defined once within a single context. It can be overwritten by a child context.
Array directive - set multiple values in single identifier. Can be used multipal times
Action - performs an action when triggered
try_files
will look for files, space separated, in turn until it finds something. If nothing is found you can set a default to =404
Inheritance straight down from parent context http, server, location.
There are implicit variables available to us, for example the $url
which equates to the url nginx variables .
Multiple sites
Digitalocean has a great tutorial on running multiple sites.
SSL
Digitalocean have a great tutorial about how to create an ssl certificate .
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /usr/local/etc/nginx/ssl/nginx.key -out /usr/local/etc/nginx/ssl/nginx.crt
Using with Node
References