Using Docker with nginx and NodeJS

The best way to learn a new technology is by doing some hands-on practice or exercise. In order to learn the basics of Docker, I was scouting for a problem and the one that captured my imagination was how to use Docker for handling static web pages and dynamic REST APIs. In this 2-part blog, I will describe the problem and the solution first and then show how I implemented the solution using Docker.

Problem description

Modern web-based applications are built using static or dynamic web pages. And these web pages in turn invoke RESTful APIs to fetch data or perform some operations on the backend. The important aspect here is that both the UI pages as well as RESTful APIs are transported over HTTP/S. So we effectively need web server(s) to serve UI pages as well as RESTful APIs.

Solution overview

While standard web servers can serve static HTML pages, the REST API processing requires web servers to support programming languages. Depending on the language the web servers for handling REST APIs can by built using NodeJS (JavaScript) or Bottle/Flask (Python) for example. But tools like NodeJS and Bottle etc do not support standard web server features like caching, proxying etc, which are useful for static web pages. So the common solution is to use both regular web servers like apache or nginx (proxy) for web pages and use NodeJS etc for REST APIs.

Solution in depth – deploying using Docker

For this Docker learning exercise we will deploy two containers – one running nginx and another running NodeJS. The ngnix server will handle all incoming HTTP/S requests. However it will proxy the REST API requests to the NodeJS process and handle the UI pages itself.

The Code

The source code for this learning exercise can be found on my Github account.

I have used Docker Compose to orchestrate the two containers. The gui-container on the Github account implements the nginx server and the api-container implements the NodeJS container. In the next installment of the blog, I will describe the code and show how it implements the solution mentioned above. I will also describe one interesting and useful feature of Docker that I learnt in this process.