AWS Elastic Beanstalk: Single Container Tricky Part


When using Elastic Beanstalk from AWS we faced some behaviors that dont fit what we wanted. Before we tell you what it is and how are we deal with, as in the post title we use single container EB. Therefor we utilize Docker and Nginx provided in that single container EB (yes this EB is Nginx included). Ok its time to show what we faced.

Elastic IP

We use load balanced cluster to serve our production web. By default EB will use public EIP in a load balanced cluster. Why could this be an issue? AWS limit EIP usage. Although it could be increased via support center, but the approval could take some times. When we need more nodes in our cluster and hit the EIP limit usage thats the problem. Beside, best practice around the web suggest to use internal network in a cluster. We decided to go with no public IP in our cluster, this is what we add in our EB config through ebextensions:

Docker log driver*

We use fluentd as our log data collector via docker log driver. First, this will need fluentd agent running in host, its simple fluentd provide official script for this here http://docs.fluentd.org/v0.12/articles/install-on-beanstalk

Then we should tell docker to use fluentd for log driver. Thanks for this, so we could figure how to do it:

Nginx*

What is special about nginx here? We need some adjustment essentially for https redirect. It could be done in our application code actually, but since nginx is in EB stack we prefer to use it. We already decided to put SSL Certificate on ELB before. ELB need a health check url in every cluster node, because SSL cert is on ELB we need to exclude health check url in https redirect. Guess what? Its trivial to do with nginx. We also add other adjustment like hide nginx version and increase client maximum upload size.

Our application capture client IP Address to log several events and this is problematic at beginning. Our application keep record ELB private IP address, its because now our app is behind two reverse proxies ELB and nginx. Nginx aready provide solution to this issue by using set_real_ip_from directive, thanks for this post so we got the big picture.

This is our final ebextensions file for nginx configuration looks like:


* As we write this post we use EB stack with Docker v1.12.6, other version might need adjustment. (Update: this Nginx configuration still usable with Docker v17.03.1-ce)