AWS Elastic Beanstalk Docker Deployment:

Running multi-container docker in Elastic Beanstalk

For production environments, Elastic beanstalk provides a powerful administrative layer for running docker containers in the Amazon ECS service under a load balancer that responds to scaling events triggered by traffic or instance failures. This 10 step tutorial will get it all up and running in less than an hr.

The basic steps for Dockerizing a code repository into docker microservices can be found in Connecting Services w/Docker Containers

Before you begin you will need an AWS account and the AWS commandline installed. You can use the digitopia-example project as your app in this example or use your own. If using digitopia-example fork the repository so you can make commits. You need to set it up before setting up EB as described in README.

If you work on multiple AWS accounts from your workstation you have probably already set up "profiles" in ~/.aws/config. If you only have a single account you can omit the --profile <YOUR AWS PROFILE NAME> from the aws commands in this tutorial.


Step 1: Create a container repository in your AWS EC2 Container Service (ECS)

It's pretty self explanatory in the AWS ECS web console. Name your repository and make note of your Repository URI <YOUR REPOSITORY URI> for future use in this tutorial. It will look something like: ######.dkr.ecr.us-east-1.amazonaws.com/name

You also need to add permissions to the repository to allow all push/pull actions on the repository for your AWS login.

Step 2: Log into container service using the aws commandline
aws ecr get-login --profile <YOUR AWS PROFILE NAME> --region <YOUR AWS REGION>  

This returns a docker command which you need to execute to connect docker commandline to your AWS account.

Step 3: Build your docker images

cd docker-assets; docker-compose build

In the case of the digitopia-example repository this makes 2 images, one for dockerassets_nginx-digitopia and one for the dockerassets_webapp-digitopia.

Step 4: Tag and push your images to ECS
docker tag dockerassets_nginx-digitopia <YOUR REPOSITORY URI>:nginx  
docker push <YOUR REPOSITORY URI>:nginx  
docker tag dockerassets_webapp-digitopia <YOUR REPOSITORY URI>:webapp  
docker push <YOUR REPOSITORY URI>:webapp  

This will label (for future reference) and upload the docker images into ECS so the Elastic Beanstalk can pull them.

Step 5: create a Dockerrun.aws.json file to describe your containers

This file is the template EB will use to run the containers. For the digitopia-example repository it looks like this (replace <YOUR REPOSITORY URI>

{
    "AWSEBDockerrunVersion": 2,
    "containerDefinitions": [{
        "name": "webapp-digitopia",
        "image": "<YOUR REPOSITORY URI>:webapp",
        "environment": [],
        "essential": true,
        "memory": 512,
        "portMappings": [{
            "hostPort": 3000,
            "containerPort": 3000
        }],
        "mountPoints": []
    }, {
        "name": "nginx-digitopia",
        "image": "<YOUR REPOSITORY URI>:nginx",
        "essential": true,
        "memory": 128,
        "portMappings": [{
            "hostPort": 80,
            "containerPort": 8080
        }],
        "links": [
            "webapp-digitopia"
        ],
        "mountPoints": []
    }]
}
Step 6: Run EB init

Initialize in your repository for the Elastic Beanstalk environment

eb init --profile <YOUR AWS PROFILE NAME>

This will ask for a name for your application

Step 7: Run locally

Test your Dockerrun.aws.json file locally

eb local run --envvars "NODE_ENV=localdev,SKIP_PASSPORT=true,SKIP_UPLOAD=true,SKIP_OG=true"  

get ip in another terminal: eb local status

connect with web browser :80

^C to kill containers when done.

Step 8: Allow instances in elastic beanstalk to access the container repository in ECS

In the AWS web cosole, add policy AmazonEC2ContainerRegistryReadOnly to the IAM role aws-elasticbeanstalk-ec2-role

Step 9: Commit

You need to commit the Dockerrun.aws.json file.

git add . git commit -a -m "checkin Dockerrun.aws.json"

Step 10: Create Elastic Beanstalk environment

The following command will build the stack:

eb create <YOUR ENVIRONMENT NAME> --profile <YOUR AWS PROFILE NAME> -i t2.small -p "multi-container-docker-1.11.2-(generic)" -s -k <YOUR AWS KEYPAIR NAME> --envvars "NODE_ENV=localdev,SKIP_PASSPORT=true,SKIP_UPLOAD=true,SKIP_OG=true"  

If all went well you now have containerized services stack running under elastic beanstalk.

You can see the results in the EB control panel on AWS. Poke around AWS EB, EC2, EC2 Load Balancer and ECS to familiarize yourself with how all these pieces are put together. Most changes to the configuration are made in EB which will trigger a rebuild of the various services as needed. In production you would probably change the environment type to "load balancing auto scaling"


Pushing updates

When you make code changes just check them into git, rebuild the affected containers then push the containers to ECS and run eb deploy In load balanced mode it will do a rolling update of all instances in batches.


Photo: Inle Lake, Myanmar (2016)
Document version 1.1