Elastic Beanstalk offers a lot of bang for your buck. Deployment, auto scaling, load balancing and database management are just some of the features Elastic Beanstalk offers out-of-the-box.
It’s hard to find a software platform that isn’t supported by Elastic Beanstalk, it currently offers support for Ruby, PHP, Python, Java, .NET, Node.JS and Go. But it doesn’t stop there, for every platform there is a multitude of platform versions and servers to run your application. Just for the Ruby environment you can choose between several versions of Ruby in combination with Passenger or Puma.
But it doesn’t stop there! Elastic Beanstalk has one more trick up it’s sleeve: The ability to run your application inside a Docker container.
There are a lot of advantages to using Docker for running your application. A very incomplete list:
- Less overhead on the environment running your application.
- Test and run your application in the same environment.
- Easy to debug. You can export a faulty container, download it and start it locally.
- Simplify configuration, less need for customising the host environment using .ebextensions.
- Faster deployments and auto scaling.
We had been experimenting with using Docker to run our stack for a while. Our first try was using Deis to run our staging environment. We saw a lot of potential and spent quite a lot of time on getting our stack to work but, in the end we simply didn’t feel comfortable with the level of stability Deis was offering.
This made us little weary of trying it again on Elastic Beanstalk but, after some initial experimentation we were sold!
If you are interested in knowing more about our experiences using Deis please let us know in the comments. If we receive enough interest we might devote an article to the subject.
There’s more than one way to go about deploying an application on an Elastic Beanstalk Docker environment. First of all, you have the choice between running a single or multi-docker container setup. For our purpose the Single Docker setup works just fine.
First, we are going to need a base docker image that we can use for our deployments:
You should of course replace
awesome_app with the name of your own organisation on the Docker repository.
Next we will create the
Dockerrun.aws.json file. This file holds the configuration needed for Elastic Beanstalk to deploy your Docker container:
The file includes the following sections:
AWSEBDockerrunVersion- Specifies the version number. 1 for single and 2 for multi.
Ports- Which ports to expose on the Docker container.
Volumes- Which volumes should be mounted from host to the Docker container.
Logging- Where to mount the host log directory to the docker container. The host log directory can be found here:
If you are already familiar with the structure of the
Dockerrun.aws.json you might notice we left out the
Image section. The above
Dockerfile will be used as a base for a Docker image that will be built during deployment by Elastic Beanstalk. For this we need to create a different Dockerfile which will be sent along with all other application files to Elastic Beanstalk during deployment.
Create the following
Dockerfile and place it in
In this example we start the application by running
puma but you could just as easily start any other application server.
For the final step we will need to pull it all together. We will be deploying from inside the
awesome-app/base:0.1 docker container. For this we will create a simple script called
deploy inside the
In the example the EC2 region has been hardcoded to
eu-central-1 but this can be changed to the region of your liking.
The script creates two files needed by the Elastic Beanstalk CLI to deploy your application:
- .elasticbeanstalk/config.yml - This file specifies the target environment for deployment
- /root/.aws/config - This file specifies the AWS credentials file needed for authentication
For the script to work it will need two environment variables:
These can be generated from the IAM console in your AWS console.
Don’t forget to make the script executable:
Finally, let’s run the script. First we will need to start a new docker container based on the
If everything went as planned you should be logged into the docker container as root.
To run the script we first have to
cd to the
/webapp directory so we can run the deploy script:
When the script is finished your application is pushed to Elastic Beanstalk for propagation to your EC2 instances, shaving a lot of time on spinning up new EC2 instances during auto scaling.
Even though running the deployment from your local machine works perfectly fine, it would be a lot more efficient to let your CI environment take care of this. At Springest we use Wercker and their Ewok infrastructure to run our specs and deploy script.
This article won’t go into detail how Wercker can be used to make the process even more efficient. If you are interested in the details please leave a comment. If we receive enough interest we might devote an article about it in the future.
Want to work at the biggest learning source in the world?