How Do You Configure Nginx in a Docker Container to Be an HTTP Load Balancer?

Updated on 11/7/17

Problem scenario

You want a computer server (e.g., an AWS instance) to be a reverse proxy (a type of landing page users do not see that acts as a portal).  You want it to relay traffic to other IP addresses.  How do you get a server with Docker to distribute traffic to other IP endpoints?

Solution
Prerequisites
This assumes that Docker has already been installed.  To install Docker on RedHat, see this link.  To install Docker on Ubuntu, see this link.  To install Docker on Linux SUSE, run this command "sudo zypper -n in docker".  If you need more directions for installing Docker, see this posting.

The caveat with Docker on Ubuntu (as of 9/6/17) is that the web servers on the back end must not be other Nginx instances in Docker.  If the servers the HTTP load balancer (running via Nginx in a Docker container) distributes to are Apache web servers, Tomcat instances in Docker, or other Nginx servers not running in Docker or Nginx in Docker containers running on a different Docker host, then there will not be a problem.

The Docker service should be running and have access to the internet.  You will need the FQDN or IP address of one or more of the web servers that the soon-to-be-created HTTP load balancer will distribute to.

Procedures
1.  Run a command like this to create the Docker container for the distributor (or HTTP load balancer) Nginx instance:

docker run --name docker-nginxbalancer --net=host nginx

2.  Use the command "docker ps -a" to find the Docker ID of the container created by the above command.

3.  Start the Docker container (e.g., with "docker start abcd1234" where abcd1234 is the container ID).

4.  Enter the Docker container with a command like this:  docker exec -it docker-nginxbalancer bash

5.  Once inside the container, use this command to enable text-editing capabilities: apt-get update; apt-get -y install vim

6.  Modify the default.conf file.
  a) vi /etc/nginx/conf.d/default.conf
  b) In the server {} section, underneath the "location / {" subsection, comment out these lines like this:

  # root /usr/share/nginx/html;
  # index index.html index.htm;

  c)  Do not comment out the "location / {" stanza itself.  Now add a new line under this stanza near the two commented-out lines (as seen above) with this content indented the same way as the original lines above were indented:

  proxy_pass http://backend;

  d) At the very bottom of the file, add these lines (but replace the IP addresses with the FQDNs or IP addresses you want traffic to go to) .

  upstream backend {
     server 10.10.0.1;
     server 10.10.0.2;
     server 10.10.0.3;
   }

  e)  You can have as few as one server stanza above.  The IP addresses can include port numbers (that is the IP address could be a socket) or be FQDNs instead of IP addresses or sockets.  The endpoints (corresponding to the IP addresses, sockets or FQDNs) can be Apache web servers, Nginx web servers, or Apache Tomcat servers. 

If the Docker host and web servers are all AWS instances, we recommend using the servers internal IP addresses (or single IP address if you only add one server to the default.conf upstream {} block).  The Docker container may be lost (inaccessible and will not start again until an AWS Security Group change is made) if you use an external IP address instead of an internal IP address.  The reason is that the Security Group(s) involved may not allow connections to external IP addresses from the external IP addresses.  Internal IP addresses are exempt from this potential Security Group problem.

Save the changes to the file (/etc/nginx/conf.d/default.conf) when you are done.  Then exit the Docker container.

7.  Stop the Docker container with Nginx. Start the Docker container.

FFR
If you want to need to troubleshoot problems with your Nginx load balancer, see this link.

Leave a comment

Your email address will not be published. Required fields are marked *