Introduction to NGINX
When I was asked to create google auth functionality and it worked on my locals, I faced a problem during deployment. The google auth and automated email send don’t work on VM. I have to deal with Nginx to handle this problem. This article is created to teach myself about Nginx.
NGINX is open-source software for web serving, reverse proxying, caching, load balancing, media streaming, and more. It started out as a web server designed for maximum performance and stability. (Nginx docs)
Installation
Nginx is installed on our ubuntu VM, here are commands to initiate:
sudo apt-get update
sudo apt-get install nginx
sudo nginx -v
I experimented with Nginx on my mac, and start installing using homebrew:
brew install nginx
sudo nginx
sudo nginx -s quit
I used sudo nginx -v
to check that Nginx is installed. sudo nginx
to start, ps -ax|grep nginx
to check that Nginx is running, and sudo nginx -s quit
to turn off Nginx.
Let’s learn by exploring how Nginx looks like in actions.
Basic Configuration
When installing nginx, a default nginx.conf will be created and it will look something like this:
user www-data;
worker_processes auto;
pid /run/nginx.pid;events {
worker_connections 768;
# multi_accept on;
}http {sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;# server_names_hash_bucket_size 64;
# server_name_in_redirect off;include /etc/nginx/mime.types;
default_type application/octet-stream;access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;gzip on;
gzip_disable “msie6”;# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Nginx config files is made up of context. Context is declared like this: context_name {}
like http{}
. It can be nested and every child context inherit parent’s config. To understand what the above script means, read this article link.
In the last two lines, there is include etc/nginx/sites-enabled/*
. Sites-enabled folder coniststs of other config files that is symlinked from /sites-available. So most of code snippets starting in server
you will see throughout the post are found in custom conf files located in sites-available. In order for the server to run, we need to symlink from sites-available to sites-enabled.
The server context defines a specific virtual server to handle your clients’ requests. You can have multiple server blocks, and NGINX will choose between them based on the listen and server_name directives.
Inside a server block, we define multiple location contexts that are used to decide how to handle the client requests. Whenever a request comes in, NGINX will try to match its URI to one of those location definitions and handle it accordingly. (Stefanos Vardalos)
Nginx to serve static content
(http://nginx.org/en/docs/beginners_guide.html)
Since I installed Nginx using brew, the default Nginx directory is located in /opt/homebrew/etc/nginx.
Quoting from nginx.org documentation, “By default, the configuration file is named nginx.conf and placed in the directory /usr/local/nginx/conf, /etc/nginx, or /usr/local/etc/nginx.” So it depends on your computer.
I created /opt/homebrew/data which consists of 2 folders: /www for storing html file and /images for storing images. Now, we’re going to replace the default ‘Welcome to nginx!’ page with my index.html.
After creating /opt/homebrew/data/www/index.html, I changed nginx.conf to point out to my new index.html.
Initially, it looked like this:
server {listen 8080;server_name localhost;
location / {
root /html;index index.html index.htm;
}
}
Then, I changed to the following:
server {
location / {
root /opt/homebrew/data/www;
} location /images/ {
root /opt/homebrew/data;
}
}
Difference:
- I deleted
listen 8080
, so now Nginx will be served on localhost:80 - The index.html page that is initially served from /opt/homebrew/var/www, now changed to /opt/homebrew/data/www/. Rendering my own index.html 😃
- If I store image.png in /opt/homebrew/data/images/, I can access that image in localhost:80/images/image.png
Nginx as a Simple Proxy Server — How We Implemented NGINX in Our Project
http://nginx.org/en/docs/beginners_guide.html
One of the frequent uses of Nginx is setting it up as a proxy server, which means a server that receives requests, passes them to the proxied servers, retrieves responses from them, and sends them to the clients.
We will configure a basic proxy server, which (1) serves requests of images with files from the local directory, and (2) sends all other requests to a proxied server. In this example, both servers will be defined on a single nginx instance.
a. Proxied Server
server {
listen 8080;
root /data/up1; location / {
}
}
This will be a simple server that listens on the port 8080 and map all requests to /data/up1 which has an index.html file.
b. Proxy Server
server {
location / {
proxy_pass http://localhost:8080/;
} location ~ \.(gif|jpg|png)$ {
root /data/images;
}
}
This proxy server config will serve image requests directly fromroot/data/images
, but will pass all requests other than that to our proxied server.
In our project, here is how we set up nginx as a proxy server.
The backend django app will listen to port 80. This conf file will be placed inside our docker. server_name
should be followed by domain that nginx will listen for. server_name _
is used as the default name for all domains to be processed by nginx. backend is the name of our backend service in docker. Thus, any request to / will be routed to backend in port 8000.
Another Example
The upstream
context defines a pool of servers that NGINX will proxy the requests to, and NGINX can perform a load balancing job to make incoming traffic distributed equally across all servers available. We can refer to the server pool’s name inside location context later.
Example from https://faun.pub/basics-of-configuring-nginx-b38c78eb113
upstream sample.server.com {
server server1_ip:port;
server server2_ip:port;
}server {
listen 80;
server_name some.server.com;
location / {
proxy_pass http://sample.server.com;
}location /test {
alias /var/www/html/customapp/;
try_files $uri $uri/ =404;
}
}
Inside the server block, a location block is defined. This parameter sets depending on the request URI. A location will match the prefix/regex given.
proxy_passwill send the request to a specified proxied server. In the above sample, this directive is used to map the location with the upstream.
Important locations:
- Add configs in -> /usr/local/etc/nginx/servers/
- Default config -> /usr/local/etc/nginx/nginx.conf
- Logs will be in -> /usr/local/var/log/nginx/
- Default webroot is -> /usr/local/var/www/
- Default listen address -> http://localhost:8080
Starting, Stopping, and Reloading NGINX
sudo service nginx startservice nginx reloadservice nginx status