This a continuation of the last post: Under the Hood of Elastic Beanstalk Part 1

We’ll go over the EB nginx setup for the docker container in this post.

EB Docker on Upstart

First, the docker container is always kept running via the upstart config /etc/init/eb-docker.conf. If you kill the process, it’ll just come back up.

# docker ps
CONTAINER ID        IMAGE                              COMMAND                CREATED             STATUS              PORTS               NAMES
163ebbeedede        aws_beanstalk/current-app:latest   "/bin/sh -c docker/b   19 hours ago        Up 19 hours         3000/tcp            hopeful_brattain
# docker stop 163ebbeedede
163ebbeedede
# docker ps
CONTAINER ID        IMAGE                              COMMAND                CREATED             STATUS              PORTS               NAMES
163ebbeedede        aws_beanstalk/current-app:latest   "/bin/sh -c docker/b   19 hours ago        Up 1 seconds        3000/tcp            hopeful_brattain
#

If you really want to stop it you’ll need to do so via upstart: stop eb-docker.

# docker ps
CONTAINER ID        IMAGE                              COMMAND                CREATED             STATUS              PORTS               NAMES
163ebbeedede        aws_beanstalk/current-app:latest   "/bin/sh -c docker/b   19 hours ago        Up 34 seconds       3000/tcp            hopeful_brattain
# stop eb-docker
eb-docker stop/waiting
# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
# start eb-docker
eb-docker start/running, process 11090
# docker ps
CONTAINER ID        IMAGE                              COMMAND                CREATED             STATUS              PORTS               NAMES
163ebbeedede        aws_beanstalk/current-app:latest   "/bin/sh -c docker/b   19 hours ago        Up 1 seconds        3000/tcp            hopeful_brattain
#

Nginx Proxies to Docker Container

You can see that the normally running container listens to the port 3000 in this case. The container will expose the port that is configured in your Dockerfile or the Dockerrun.aws.json according to the AWS documentation. The script with that logic that selects the port to expose is actually located at /opt/elasticbeanstalk/hooks/appdeploy/enact/00run.sh. EB configures nginx to proxy port 80 to this exposed container port with this config file: /etc/nginx/conf.d/elasticbeanstalk-nginx-docker-upstream.conf

We can curl the docker port directly.

# curl -s -v -o /dev/null 172.17.0.9:3000 2>&1  | grep '< HTTP'
< HTTP/1.1 200 OK
#

We can also curl nginx port 80 to make sure the proxy is working all the way from nginx to the container.

# curl -s -v -o /dev/null localhost:80 2>&1  | grep '< HTTP'
< HTTP/1.1 200 OK
#

Configure Docker Container Server Concurrency

Configuring nginx to proxy to another webserver is pretty typically. Unicorn and puma are commonly use and they are configured so that they have multiple processes or threads to handle concurrency. In the EB case, nginx proxies to the server within the docker container itself. Knowing this, it is important for scaling reasons that the docker container server is configured for concurrency properly. You’ll want to configure your container to have the right number of workers or threads to maximize the RAM and CPU on the instance efficiently. EB is usually used to run only docker container on each AWS instance. So it is crucial that we configure that docker container’s server to run more than 1 process or thread or else we’ll be likely wasting resources and worse not scale.

Each application is different in how it consumes CPU and uses RAM so you’ll have to play with it. Here are simple examples for unicorn and puma.

ELB

Lastly, EB sets up and ELB so traffic gets load balanced to port 80 on each instances in the environment. So the overall routing goes: client -> ELB > nginx -> docker.

Curl the ELB endpoint to make sure that it’s working all the way from the ELB to nginx to docker.

$ curl -s -v -o /dev/null "http://your-custom-endpoint.elasticbeanstalk.com" 2>&1 | grep '< HTTP'
< HTTP/1.1 200 OK
$

Related Posts: