Docker Compose with nginx and NodeJS

Page content

If you are a follower of this blog, you might have read about Using Docker with nginx and NodeJS. In this blog, I will discuss the code to build  the two containers using Docker Compose. Finally, I will highlight an important capability of Docker that I learnt in this exercise. The source code being referred in this blog is available on GitHub.

Acknowledgement: I was inspired by this blog and wanted to take it further using Docker Compose.

Docker Compose - background

Docker Compose is a tool to build and coordinate multi-container applications. You use a YAML file to define different containers and any relationship between them. Docker Compose uses this YAML file to start those containers. We can continue to use the Dockerfile as a building block for Docker Compose.

Docker Compose YAML

Docker Compose YAML

Docker Compose File structure

Docker Compose File structure

As you can see from the GitHub repository, I have two containers defined in my docker-compose.yml file. The YAML file shows that the two “services” are built using the Dockerfile specified for each of the containers. The steps in two Dockerfiles are fairly straightforward. They create an Ubuntu based container, install the necessary software packages and copy a few files to configure nginx and NodeJS.

nginx Proxy

In the previous blog, we showed that nginx is used to serve static HTML files and to forward (proxy) the API requests to NodeJS. Here is the screenshot of the file I use for nginx configuration.

Docker Compose YAML

Docker Compose YAML

This config file configures nginx to listen on port 80 for HTTP requests. If the requests comes to a root folder &"/", it is redirected to the Application represented by “/app” on the same host. However if the request is for API represented by “/app/api” URI, then nginx will proxy the request to “API Server” on port 9090. If you look at the Dockerfile for the NodeJS container, you will see that it is listening on port 9090. The key thing here is the keyword apiserver. How does nginx know what is the IP address for the NodeJS container?

Links are important concepts that help Docker containers communicate with one another. It is a good practice to use host names instead of hard-coding IP addresses when one container needs to communicate with another. But host names and IP addresses have to be mapped automatically. This is where the concept of Link comes into picture.

The YAML file has a stanza for the GUI container as follows:

links:
    - api:apiserver

The keyword, api, refers to the “container” mentioned earlier in the YAML file.

services:
    - api:
        build: api-container

The effect of this link is that Docker will take the IP address of the container named api and map it to the host name apiserver inside the GUI container. The /etc/hosts file is used for this purpose.

In  real world scenarios it is common to have container distributed across servers in a datacenter. Therefore IP address may not be known upfront and may also change over the course of time. Docker Links provide a crucial capability to ensure that containers are able to communicate with one another using host names and let Docker orchestrate the mapping of host names to IP addresses.