When you're used to developing on Windows, you've almost certainly used IIS
to serve web pages, applications, APIs etc. This was always my experience and, like so many other Windows products, it spoils you by doing a lot of the administration automatically. Moving to a Linux-based job was a bit of a shock - I asked which web server we were using and was told "nginx
" a "reverse proxy", with no further explanation. So I started looking through the documentation, and found that nginx
is a whole world of fun, which can solve most of your web-based requirements and more.
So, What's A Reverse Proxy?
Let's start from the very beginning (it's a very good place to start!). In the real world, a proxy is a stand-in that does something you instruct them to; it acts like you, but isn't you, and doesn't look like you. In networking, it's similar; a proxy sits between your systems and others, typically the internet. It hides the identity of individual machines making requests from servers, so it can avoid restrictions on the network. It can filter out undesirable traffic, cache data to reduce traffic levels, or any other manipulation you want to do. Using a proxy to do this means everything happens on the proxy, rather than forcing individual clients to do everything themselves:
A reverse proxy does, unsurprisingly, the reverse of this. It sits in front of a number of servers, and handles client requests, routing them to the correct server. While it does this, none of the clients need to know anything about the individual servers, they just see the reverse proxy:
Reverse proxies can act as load balancers, caches, and handle SSL/TLS encryption and decryption. They can even calls to different parts of your domain to different servers, so a static page that doesn't use much processing power can be hosted on one machine, but other parts of your site that use more power are handled by others.
What Does nginx Do Then?
As well as offering everything a reverse proxy normally does, nginx
has some very useful extra features. For example, if you don't want to run an HTTP server on a separate machine that's fine - nginx
has its own built-in HTTP server that will run on the local machine. It does everything you could want from an HTTP server, including streaming and handling Rest APIs.
As well as this, you can use it as a mail proxy AND to proxy TCP and UDP data.
So, Should I Use It?
Yes. nginx
is the world's most popular web server. It's efficient, well supported and fast. Even if you use another server (for example IIS
on Windows) you should look into nginx
. They even work together so you can use nginx
to proxy messages onto your Windows systems. The host operating system doesn't matter, so you can have multiple servers running different operating systems, with all of the proxy work being handled by nginx
.
Are There Any Disadvantages To Using nginx?
I haven't found any specific disadvantages with nginx
, apart from all of the configuration being text based. This is mostly from my own experience of being used to using a UI in Windows. You get used to it quite quickly though, and the documentation is very good.
For example, below is a bash script which installs nginx
on an Ubuntu server, and configures it so that all HTTP requests to the root directory / are forwarded to another server on the network at myserver.local
:
#!/bin/bash
sudo apt update && sudo apt upgrade -y && sudo apt-get install -y nginx && sudo apt autoremove -y
echo "server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
location / {
proxy_pass http://myserver.local:80;
proxy_buffering off;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
}
}
" > /etc/nginx/sites-enabled/rating
rm /etc/nginx/sites-enabled/default
sudo systemctl restart nginx
There are a couple of things worth noting here:
It was quite difficult to find an example showing how to use nginx
to redirect HTTP to a separate server. Most of the examples I found show something similar to the server block of code above. Some sites say to add it to nginx.conf
(don't!). Others say add it to /etc/nginx/sites-enabled/default
. If you do that, you'll get a log message like this:
Mar 21 13:09:55 jason-ubuntu systemd[1]: Starting nginx.service - A high performance web server and a reverse proxy server...
Mar 21 13:09:55 jason-ubuntu nginx[26242]: 2025/03/21 13:09:55 [emerg] 26242#26242: a duplicate default server for 0.0.0.0:80>
Mar 21 13:09:55 jason-ubuntu nginx[26242]: nginx: configuration file /etc/nginx/nginx.conf test failed
Mar 21 13:09:55 jason-ubuntu systemd[1]: nginx.service: Control process exited, code=exited, status=1/FAILURE
Mar 21 13:09:55 jason-ubuntu systemd[1]: nginx.service: Failed with result 'exit-code'.
Mar 21 13:09:55 jason-ubuntu systemd[1]: Failed to start nginx.service - A high performance web server and a reverse proxy server...
The way to add a new redirect to nginx
, and have it actually work, is to do the following:
- Put the server block, as shown above, into a file in the
/etc/nginx/sites-enabled
directory. The name of this file doesn't really matter, so it's best to make it reflect the server or service that you're proxying. - Delete the
/etc/nginx/sites-enabled/default
file. - Restart the
nginx
service.
Looking at the example script above, these three steps are carried out in the last three lines.
One thing worth noting, if you're running nginx
in production, is that you can make it read configuration updates without restarting. Just send the master process a HUP signal.
One other error I received was this:
nginx reverse proxy gives "502 Bad Gateway"
This one was my fault - make sure the address AND port you're redirecting to are correct.
Summary
If you need a web server, load balancer, proxy or reverse proxy on Linux, or even on Windows, try nginx
. It's almost certainly the right way to go.