Join egghead, unlock knowledge.

Want more egghead?

This lesson is for members. Join us? Get access to all 3,000+ tutorials + a community with expert developers around the world.

Unlock This Lesson
Become a member
to unlock all features

Level Up!

Access all courses & lessons on egghead today and lock-in your price for life.


    Scale Docker Horizontally with Nginx Load Balancing

    Mark ShustMark Shust

    Node.js apps built with Docker cannot scale horizontally by themselves. In this lesson we will spawn out multiple Node.js processes/containers, and move the incoming request handler to an Nginx proxy to load balance and properly scale our Node.js app.



    Become a Member to view code

    You must be a Member to view code

    Access all courses and lessons, track your progress, gain confidence and expertise.

    Become a Member
    and unlock code for this lesson




    Instructor: Let's make a directory called nodejs that contains our app files. Within that, we will create a simple Node.js app that responds, "Hello world from server," followed by the name of our server, which will define from an environment variable.

    Let's then create a Docker file that simply kicks off our Node.js process. Then we will build our app image with "docker build -t app-nodejs .". Let's start two Node.js processes. We'll start the first server with a server name of chicken, and a name we can reference later, chicken.

    We'll do something similar with our second server, but with the name steak for both. Note that Nginx will be handling our external requests, so we do not need to bind any ports of the app containers back to the host.

    Our containers will only be accessible from other Docker containers. Since these containers will not be directly accessible by a public network, this will also add an additional level of security to our app. Let's create a new Nginx directory in the root of our project and enter it.

    In this directory, we will create a new file to contain our Nginx configuration, named Nginx.conf. The purpose of our Nginx process is to load balance requests to our Node.js processes. Let's create a server block with a location block underneath, preceded with a slash.

    Within this block, define a proxy_pass directive, followed by http://, followed by any arbitrary value. We'll use app here, followed by a semicolon. What we're telling Nginx to do here is to listen at the root path of our web server, and pass all requests through a proxy named app.

    Let's go ahead and define that proxy. Create a new upstream block, followed by the name of our proxy, app. Next, we will follow it with a line started with server, followed by the name of our first server, chicken, and the default port, 8000.

    We will repeat the line again, but this time with the steak server. The upstream block we define here tells Nginx which server to proxy requests to. We can define as many lines here as we want. Nginx will treat requests defined within this group with a round robin balancing method. You can even define weights on the servers with the weight option.

    Next, let's create an Nginx Docker image that just copies over our file to the default configuration file location. Let's build this image, and name it app-nginx. The final step is to start our Nginx container, and map port 8080 on the host to port 80 on the container.

    We will then use the link directive to link our chicken and steak servers, making them accessible within the container. If we use curl to hit our Nginx server on port 8080, we will see that Nginx is properly routing requests to our chicken and steak Node.js servers in a round robin fashion.