-
Notifications
You must be signed in to change notification settings - Fork 0
Proxy web applications using nginx
According to a blog on the nginx website, nginx is a high-performance load balancer, cache, and web server, which has found growing usage. With nginx, we can use a server with a single public IP address to host multiple web applications, each with its own port number and/or private IP address, e.g., http://my.domain.com
, http://my.other.domain.com
, http://localhost:5000
, http://localhost:9999
.
This is made possible by the fact that Internet browsers send domain names inside HTTP requests. When the request is received by the nginx server, it parses the requested domain name and URL, then routes the HTTP request to the hosted web server of the respective web app. That app processes the request and responds as if it were accessed directly.
Note that you do not want to parse HTTP requests yourself. There is a plethora of tools and technologies that can do that for you, including nginx. nginx can proxy multiple web applications using a single VM or physical server.
The simplest process for installing nginx on a Mac uses Homebrew. From the console, verify that Homebrew is installed on your machine.
brew --version
If Homebrew is not installed (you did not gee a version number), install it by following the instructions posted on the Homebrew site. Since Homebrew can self-diagnose, verify that everything is is fine and works how it should. If there are issues, Homebrew will report back to you. Fix any reported issues before moving on.
brew doctor
Ensure that you have the latest version of Homebrew and that it has the most up-to-date list of formulae available from the main repository.
brew update
You should expect to see "Already up-todate". Here are a few other Homebrew commands that may interest you. Now you are ready to install nginx by simply following this command.
brew install nginx
Verify installation by checking what version got installed -- nginx -v
. You should see 1.8.0 or higher if installation was successful.
When installation in complete, you can enter the command below in your terminal to start nginx.
sudo nginx
Be sure that you have a non-root user account with sudo
access configured on your system. Login with that account and update you list of packages to ensure that you are accessing the most up-to-date information by issuing the command below from a terminal.
sudo apt-get update
Installation of nginx is as easy as following this instruction.
sudo apt-get install nginx
Running nginx -v
will verify whether your installation was successful by displaying version number 1.4.6 or higher.
When nginx is successfully installed, it will start automatically.
In your web browser, navigate to http://nginx.org/en/download.html and click on the version of the nginx installer that you wish to use to complete your installation. You should select the Mainline version or the Stable version.
Launch the Command Prompt from the Run Window. One of the quickest ways to do so is to use the Run Window (press Win+R on your keyboard to open it) shortcut. Now type cmd
or cmd.exe
and press Enter. Thee are at least 7 Ways to Launch The Command Prompt in Windows.
Unpack the nginx installation file you downloaded, then go to the nginx created directory and then run nginx. Here is an example for the drive C: root directory:
cd c:\
unzip nginx-1.9.14.zip
cd nginx-1.9.14
Note: nginx/Windows runs as a standard console application (not a service), and it can be managed using the following commands:
nginx -s stop // fast shutdown
nginx -s quit // graceful shutdown
nginx -s reload // changing configuration, starting new worker processes with a new configuration, graceful shutdown of old worker processes
nginx -s reopen // re-opening log files
Upon successful installation of nginx, you can start it by entering the command below in your command prompt window:
start nginx
According to Wikipedia, a proxy server is a server (computer system or application) that acts as an intermediary for requests from clients seeking resources from other servers. Suppose that your web browser is making requests for resources from an AngularJS front-end application that is hosted at address http://my.domain.com:5000
. Suppose that the backend API associated with this front-end application is hosted at address http://my.domain.com:5001
. Note the different port numbers.
Instead of entering http://my.domain.com:5000
in your browser to access the front-end OR http://my.domain.com:5001
to access the backend API, it might be more convenient to use the following addresses:
-
http://my.domain.com
to access the front-end application -
http://my.domain.com/api
to access the backend API
The good news is this can be accomplished by proxying through an nginx server. All that's need is to make a few configuration changes, as described below.
On Mac OSX, the configuration file is located at /usr/local/etc/nginx/nginx.conf
.
On Ubuntu, the configuration file is located at /etc/nginx/sites-available/default
.
On Windows, the configuration file is located at \path\to\nginx\conf\nginx.conf
.
With admin or sudo
privilege, save a copy of your original config file (in case you make a mistake and wish to revert back to it) with a .original
extension. Now you can make changes with your favorite editor to the config file (not the copy). You need to open this file with admin or sudo
privilege, so you can save your changes.
In your nginx config file, find a server
block. It should look something like this:
server {
listen 80;
...
location / {
...
}
...
}
You can choose to change the port number from 80 to something else, if you choose, but the default http port number, 80, is perfectly fine. Reaffirm that your nginx installation was error-free to ensure that you are at a solid starting point.
sudo nginx -s stop && sudo nginx
sudo service nginx restart
nginx -s reload
Open your web browser and point it to http://localhost
. If you changed the default port number from 80 to another port number, say 9000
, then you would point your browser to http://localhost:9000
instead. You should see the default nginx index page displayed in your browser.
Suppose we want to configure nginx to route requests for /
to http://localhost:5000
and requests for /api
to http://localhost:5001
.
+--- host --------> AngularJS on localhost:5000
client--> nginx --|
+--- host/api ---> node.js on localhost:5001
To route these requests, we need to edit the config file. Find the server
block noted above and make these changes.
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://127.0.0.1:5000;
}
location /api {
proxy_pass http://127.0.0.1:5001;
}
}
You will notice that We have not changed the port number on which the nginx server listens, that is, on port number 80. We have, however, added two location
blocks. Each location
block tells nginx what to do when it receives requests. Inside the location
blocks we use proxy_pass
to tell nginx to forward requests to the server listening on the indicated port number. In our case, location /
instructs nginx to forward requests to http://localhost:5000
--the AngularJS front-end application and location /api
instructs nginx to forward requests to http://localhost:5001
--the backend API application server.
After making these changes, save the config file, start both the AngularJS and backend API applications, and restart nginx.
Pointing your browser to http://localhost
should now display your AngularJS application. In like manner, pointing your browser to http://localhost/api
should now display your backend API application, or maybe not. You probably got a 404 error
.
The reason that you got the 404 error
is that your backend application is is expecting requests from /
, but instead got requests from /api
.
To resolve this issue, we need to rewrite the URL so that it matches the URL that the backend server is expecting. The config file needs to be update accordingly.
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://127.0.0.1:5000;
}
location /api {
rewrite ^/api(.*) $1 break;
proxy_pass http://127.0.0.1:5001;
}
}
Note the change in the location /api
block. This rewrite command uses a simple regular expression that transforms routes like /apiSOMETHING_ELSE
to /SOMETHING_ELSE
in the incoming HTTP requests.
Saving the config file and restarting nginx should cause everything to work as expected.
In a live environment, you may want to configure SSL to protect sensitive information. There are several Certificate Authorities (CAs) that you can use to issue you a certificate. Or you can choose to create a self-signed certificate. Note that your browser will warn you that the self-signed certificate is not trusted. It is OK to use self-signed certificates for local testing. This is exactly what we will do.
Once you have the certificate and a private key stored on your machine, you can setup SSL in nginx. You need to modify our previous server block to the following:
server {
listen 443 ssl;
server_name localhost;
ssl_certificate /path/to/ssl/cert.pem;
ssl_certificate_key /path/to/ssl/key.pem;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
location / {
proxy_pass http://127.0.0.1:5000;
}
location /api {
rewrite ^/api(.*) $1 break;
proxy_pass http://127.0.0.1:5001;
}
}
Now if you access https://localhost
your SSL setup should work. Be sure you are accessing the certificate file and private key correctly. You will need to know where these are stored so you can access them correctly.
The last thing that we need to do is ensure that all requests are protected. To do so, we need to rewrite all http
requests to https
while maintaining sub-domains
. This can be done by configuring another server
block like this:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 301 https://$host$request_uri;
}
This will forward all requests that are made on port number 80 to port number 443. That is to say that all http requests are rewritten to be https requests.
In this blog, we provided instructions for installing and running nginx and using it to proxy multiple web applications. We also described hot to configure SSL in nginx. Using nginx in front of your application servers can improve their security and make them less susceptible to attacks.