nginx¶
This is a quick reminder about a few tricks in nginx. For me, nginx is the tools that solves the question:
- How can I serve multiple web apps from a single server with a common root?
- How can I serve multiple domain from the same server?
Usually, the nginx root folder is stored under /etc/nginx
. Note that
adaptation (usually path) might be required between linux distributions.
First of all, when you distribute multiple web app, it is much easier if you can have multiple domain names: web apps will have their routes and avoid paths conflict. In this case you will create server block for each domain.
Tips: pay attention to the slashes (/
) it the path, as nginx mainly
concatenate strings, so you might accidentally have double slashes in
your path which usually leads to unintended consequence.
Server blocks¶
Server blocks usually lives in the conf.d
or sites-availables
server {
listen 80;
listen [::]:80;
root /var/www/your_domain/html;
index index.html index.htm index.nginx-debian.html;
server_name your_domain www.your_domain;
location / {
try_files $uri $uri/ =404;
}
}
where your_domain
is replaced by the domain you own. The root
directive provides the root of your web app, the folder needs to be
reachable by the process which started nginx. If the server block is
defined in sites-availables
, you need to create a symlink into the
sites-enabled
folder.
Root directive¶
The root directive provides the root path of your request. In the
previous server block, the response from nginx
to the request on the
path www.your_domain/css/file.css
will be the filer located under
/var/www/your_domain/html/css/file.css
, because
/var/www/your_domain/html
was defined as the root and /css/file.css
is the path requested. If the files does not exists, the
404 (not found)
answer is returned.
Nginx has concatenated the root with the path.
You can change the root for each location
directive, which can handy
for distribution under several folders (see later).
Static file distribution through alias¶
Usually, you desire to use some path of your domain to target different
folder because they serve the files for your webapp. Most webapp are
defined as if they were placed on the root folder, so if the web app is
distributed under /my_webapp
the associated assets files (javascript,
css, images) will usually be unfound. To solve this problem, we use the
alias directive. In a server block (the default or any other), the
following directive will alias the www.your_domain/my_webapp
to
/var/www/my_webapp/html
.
location /my_webapp {
alias /var/www/my_webapp/html;
}
The consequences are that nginx will answer to request
www.your_domain/my_webapp/css/file.css
with the file
/var/www/my_webapp/html/css/files.css
, concatenating the alias and the
path. If root instead of alias was used, nginx would have returned
/var/www/my_webapp/html/my_webapp/css/file.css
, because nginx always
append the full path to the route, whereas alias replace the the match
path with the value provided to alias.
In my personal experience, you will use and abuse alias more often than root.
Proxy pass¶
When creating web apps, you will often create a backend server. This
server will usually be connected to some port under root (e.g. 8000,
8050, 8081). Under development, you will often use localhost:8050
as
domain. In production, you will launch the same program which will still
listen to the same port. However, you want your user to call a path on
your_domain
. The proxypass directive is the solution to
this problem.
location /backend_path {
proxy_pass locahost:8050;
}
Hence the for each request called to my_domain//backend_path/data
, the
backend will match it to /data
.
Obviously you can use nginx to also perform some indirection
location /backend_path/x {
proxy_pass locahost:8050/y;
}
In this case, under the request my_domain//backend_path/x/data
, the
backend will return the handler registered under the route /y/data
.
Regex path¶
Regex can be used to match multiple paths in nginx. You start a regex
path by adding a tilde ~
sign after location and then using standard
regex notation to reuse the match parts.
location ~ /images/(.+)$ {
try_files /other_images_folders/$1 =404;
}
Multiple source folder¶
It might happens that your apps call the same path, but the content is located in different folder. In this case, we can combine root and regex to sovle the issue.
location ~ /images/(.+)$ {
root /var/www;
try_files /my_webapp/images/$1 /your_domain/images/$1 =404;
}
Here nginx will try to server /images/file.jpeg
from
/my_webapp/images/file.jpeg
before /your_domain/images/file.jpeg
.
HTTPS¶
In order to promote the connection to https, you will need to change the server blocks and define the path of your certificates.
server {
listen 443 ssl;
server_name www.example.com;
ssl_certificate path/to/www.example.com.crt;
ssl_certificate_key path/to/www.example.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
}
Usually, you will want letsencrypt (if you own the domain name) to save this for you.
Websocket¶
In order to allow websocket, you must upgrade the connection. For this you can adapt the following snippet under the desired location:
location /shadow-cljs/ {
# upgrade to websocket
proxy_pass http://localhost:9630/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
Links¶
- https://nginx.org/en/
- Digital ocean guide
- An Introduction to DNS Terminology, Components, and Concepts