Basic Serving and Proxying in Nginx
“Knowledge isn't power until it is applied.”
— Dale Carnegie
Prologue
“nginx [engine x] is an HTTP and reverse proxy server, a mail proxy server, and a generic TCP/UDP proxy server, originally written by Igor Sysoev.”
- Nginx
So in this article, I’m going to talk about the basic use of Nginx proxying, including:
All these are done on a Ubuntu server. 😉
If you are familiar with these basic knowledge, you may want to check out Tips on Nginx Configuration first.😉
Setup Nginx
Before we use it, let’s have a brief look at Nginx.
First, we can get Nginx by a simple apt
command.
1 | sudo apt install nginx |
If you accidentally corrupted your Nginx configuration, you can use
apt purge nginx
to remove it completely, and then reinstall it.
1
2
3 sudo apt purge nginx nginx-common nginx-full
sudo apt install nginx
nginx -t
Then, we’ll write some basic configurations in /etc/nginx/conf.d/default.conf
. It tells Nginx to listen to port 80 requests and the server name it works on.
1 | server { |
If you have multiple profiles, you can then write different .conf
under /etc/nginx/conf.d/
, and Nginx will load them all.
To launch Nginx, you need these two commands, once and for all, unless you stop it permanently.
1 | sudo nginx |
Every time you make any change to .conf
files, you may want to reload Nginx, here is how to to it.
1 | sudo nginx -s reload |
And at last, if you want to stop Nginx, you can force terminate it immediately, or let it stop itself after all current works finished.
1 | sudo nginx -s quit # stop after current process finishes its work |
Serving Static Files
Reference: Serving Static Content
Now, let’s begin with the easiest part - serving static files.
In our Web service, we may want our resources accessible via URL. For example, in Django project, the static/
and media/
folder will be exposed directly to URL when DEBUG
set to True
. However, Django won’t serve static files in production, when Nginx is needed.
In order to map URL to server directory, we can add location
sections in server
. For example, if we want to map /media
route, we can add a location
section called /media/
. This tells Nginx to handle all URL routes begin with /media/
using schema defined in this section.
And in location
section, we need to assign a root directory to tell Nginx to look for /media/
folder under this root. This way, Nginx will look for local file /home/wwwroot/media/avatar/1.png
when receives URL /media/avatar/1.png
.
1 | server { |
However, if you don’t want the location appended to root
, i.e. you want have /home/wwwroot/avatar/1.png
when receives URL /media/avatar/1.png
, you can use alias
instead of root
. So your configuration will be like this.
1 | server { |
If we have several static file routes, we can write root
outside location
to make it visible for all location
sections, if it is not explicitly declared within.
1 | server { |
Basic Proxying
It is really convenient to use Nginx for backend API proxying, as it could hide annoying port suffix.
Proxying HTTP Requests
Basically, if we want to proxy our API for port 5000, we can simply write this. The only thing to notice is that, in order not to confuse API routes with others, such as static files, we can add a simple /api/
prefix to all our APIs.
1 | server { |
In this way, we can use xx.xx.xx.xx/api/your_api_route
instead of xx.xx.xx.xx:5000/api/your_api_route
.
Proxying WebSocket Requests
Reference: WebSocket Proxying
WebSocket is a way you can use to exchange data between client side and server side, regardless of whether there is a new request or not. In fact, it is a GET
request, but then get a protocol upgrade when connection established. Then how to proxy for it?
Almost the same as HTTP requests, but with some more information. Also, you may add a /ws/
prefix, or whatever you like to avoid confusion.
1 | server { |
Here, we set the http version and headers to upgrade GET requests to a WebSocket connection. According to Nginx official site, the default timeout for a WebSocket connection is 60 seconds, which might be a little too short for your project. You can manually set it to any value you like. 😋
For WebSocket, instead of a long timeout, sending heart beat might be a better option.
Troubleshoot
403 Forbidden
Sometimes you may encounter 403 Forbidden when serving static files, don’t panic. It is most likely related to some permission issue. So let’s check it out.
First, let’s see who is running Nginx. We can use ps aux | grep nginx
to find relevant processes. We can see that it is www-data
, which is, obviously not us.
So we need to change the owner of the Nginx worker process. First open /etc/nginx/nginx.conf
(need sudo
), and you’ll see a user
option on top of the file. Change the default www-data
to your username.
1 | # user www-data; |
You need to make this user the same as the owner of the files you want to serve. Usually, it is you.
It must be the root configuration file nginx.conf
, not any custom ones.
After this, use nginx -s reload
to reload the nginx. And here we go, no more 403 Forbidden! 🎉
Epilogue
Well, this is merely the basic use of Nginx proxying. Explore more on your own. 🙂ᓚᘏᗢ