nginx

Read the previous part on nginx - serving static files.

It's often assumed, that if you split a web application into a back-end API and front-end static files, you should have two separate servers for them. While this might be a good idea from an architectural point of view, you might want your end users to see the product as a whole. Fortunately, with nginx you can easily set up just that by making it act as a reverse proxy.

What is a reverse proxy?

Being around software development, you might have heard the term proxy server. It basically is a solution in which multiple incoming requests are forwarded (possibly with some in-place modifications) to some destination server. Once those requests are processed, their responses are being sent to their respective origins. With reverse proxy the situation is slightly different. This time there are multiple servers on the other side of the proxy, so that once the request reaches the proxy, it has to be checked in order to determine which destination server should take over. This way you can expose one port to the outside world while still having multiple services working separately underneath.

Reverse proxy configuration

Setting up nginx to act as a reverse proxy is incredibly simple because you just need to configure which request paths should be redirected to an existing, working application server. Given that we have some back-end running on address localhost:3000, we just need to define a location directive with another directive inside - a proxy_pass that will describe a location of our back-end server:

location /api/ {
    proxy_pass http://localhost:3000/;
}

From now on, all requests that start with /api will be redirected to that server. If the server exposes an endpoint /hello, then the users would need to access OUR_SERVER/api/hello to access it.

When nginx is acting as a reverse proxy, we are able to make some small tweaks to the request going in and out. For example, we can add some custom HTTP header going to the back-end with:

location /api/ {
    ...
    proxy_set_header custom-header "some-value";
}

We can also add some headers on the other side, that is to the response going back to the client with:

location /api/ {
    ...
    add_header another-header "another-value";
}

This can also be used to overwrite headers' values or clearing them (by overwriting with "").

Full configuration

The full nginx.conf file (an extended version of that from the previous post) should look like this:

events {}

http {
    server {
        listen 80;

        root /www;
        index index.html;

        location / {
            include  /etc/nginx/mime.types;
            try_files $uri $uri/ /index.html;
        }

        location /api/ {
            proxy_pass http://localhost:3000/;
        }
    }
}