Amazon Web Services (AWS) Elastic Beanstalk (EB) is a service to deploy your code. This easy-to-use service works as a Platform as a Service (PaaS). It supports familiar web applications, such as PHP, Node.js, Ruby, Python, Java and .Net. You can simply choose your software stack and upload your code. AWS will take care of the provisioning of the environment, deploying the code, load balancing, auto scaling, and health monitoring. At the end of the process, it prints a url used to access the application.
Recently, AWS added support for Docker containers. Before Docker, EB limited your choices to available stacks in the drop-down list. This forced you to choose predefined versions offered by AWS. For example, by default, PHP on EB runs on Apache. If you want to replace Apache with Nginx+PHP-FPM, there is no way you can do that. Customization of Amazon Machine Images (AMI) used in EB is very limited.
But now Docker is enabling flexibility for users to deploy any software stack in EB.
You are no longer solely dependent on software versions supported by EB. You can run whatever you want or need to in a container, and deploy it to EB. You can run multiple Tomcat or MySQL servers, or even multiple Apache servers, in a single container. You can even run your own customized Java service in a container and deploy it to EB.
Sound interesting? Ready to evaluate Docker? Then let’s discuss how you can deploy a Docker container in EB using 10 easy steps.
There are three ways you can deploy docker containers in EB. We assume you already know about the Docker concepts. If you don’t know about Docker, you can get a quick study here.
Here are the three ways:
1. Create a Dockerfile and upload it to EB.
2. Create a Dockerrun.aws.json file to deploy an existing Docker image.
3. Create a zip file with Dockerfile, Dockerrun.aws.json, and any application file, then upload to EB.
Dockerrun.aws.json: This is specific to AWS EB. This describes how to deploy a container in EB. (Learn more here.)
In the following 10-step tutorial, we are describing how to deploy a pre-baked Docker container from a Docker repo to AWS EB.
1. Create S3 bucket.
2. Commit Docker image.
Create a Docker image using all the required packages installed, the deploy the code. If the database is outside of the container, then be sure you have deployed the updated code.
Commit the docker image to Docker repo.
3. Create Docker Authentication configuration file:
- Login to Docker repo using Linux terminal.
$ docker login
- It prompts you for the logins and email. Once you enter the credentials, Docker creates .dockerconfig file in the user's home directory.
- Upload the dockerconfig file to the S3 bucket. EB will read this file to get the access to Docker repo.
The config file will then look like this:
4. Create Dockerrun.aws.json
This file describes how to deploy a container in AWS EB. Please see the configuration file here:
In the Authentication section, we have provided the bucket name and key value. Key is the location for the dockercfg file. Here, we have created a folder called “docker” in the flux7.com bucket and uploaded the configuration file into it. You may notice that we have renamed .dockercfg to dockercfg. You can rename it to whatever your desire. Using dockercfg EB pulls the container from the Docker private repo. The Ports section describes which ports are to be exposed from the Docker container. AWS Elastic Beanstalk uses the ContainerPort value to connect the Docker container to the reverse proxy running on the host. We run Apache inside our container, so we need 80 port to be exposed. The EB instance runs Nginx as a proxy. You can add configurations for logging and file system sharing, too. You can see more of this at here
5. Create Dockerfile
When you begin a Docker container, it doesn't run any default services. So, we need to pass on a command to start the services. By using supervisor, you can start multiple services automatically while the container starts. (Learn more here.) We now have saved a container with Apache, MySQL and PHP installed and our application deployed. It’s now time to push the container to Docker repo. Below is the Dockerfile we have created. This installs supervisord at the container startup and uploads the supervisord.conf:
6. Create supervisord.conf
Below is the example supervisord.conf file we have created. This file is responsible for starting the required services in container.
It’s designed to allow SSH, MySQL and Apache services to begin at the container start up. You can add as many services here as you need to start at the container boot-up.
7. Create AWS IAM Role
Create an IAM role and attach the user policy with S3 bucket access.
8. Compress the files into a ZIP
Now ZIP all files into a single file.
zip flux7-env.zip Dockerfile Dockerrun.aws.json supervisord.conf
Note: Do not copy them into a directory and zip the directory. EB doesn't read the directory zip.
9. Create ELB environment
i. Login to AWS Console and navigate to the Elastic Beanstalk page.
ii. At the right side top, click “Create New Application.” Application Name: Give any name for your application. Example: flux7-dev. Description: Add some description. Then click Next.
- Environment Type - Environment Tier:Select “Web Server 1.0” (Learn more here.) Predefined configuration: Select “Docker” from the drop-down menu. Environment type: Choose “single instance” or “auto scaling.” For demo purpose, we chose single instance.
- Application Version - Select “Upload Your Own” and upload the zip file created in the above step. Then click “next.”
- Environment Information - Environment name: Give your desired name to the environment. Example: flux7-dev. Environment URL: Provide the URL for your application. This is only for internal purposes. Description: Add some description.
- Additional Resources - You can select to create an RDS instance with EB. If you choose the RDS, then you will have to update the application code to point to the RDS instance. Select “Create the environment inside a VPC.” Then click “next.”
vii. Configuration Details - Instance type:Choose desired instance type. At least choose m1.small to make the app work without any hiccups. EC2 key pair:Select the “KeyPair” for the instances launched by EB. Email address: Enter your email address to receive the notifications from CloudWatch. Instance Profile: This is important. You need to choose the IAM role created above.
viii. Environment Tags: You can add any tags you want or leave them blank.
ix. VPC Configuration - VPC: Select a VPC from the drop-down list to create the instance. Select Subnets:Choose the subnets from the table shown. You may only select one EC2 subnet per AZ. VPC Security Group:This is the security group for the instances created by EB.
x. Review the configurations and click “Launch”: In a few minutes, you will have the servers provisioned and the Docker container deployed. If everything goes as expected, environment turns from the grey color to the green color. Now, you can access the application with the EB url. In case the environment fails to provision or turns to the red color, you can check the Events section for the details.
10. Update Docker Containers
If you want to deploy new code to the EB, then you need to create a new Docker image and push it to Docker repo.
If the Docker image name is the same, then, by selecting rebuilding, the environment will deploy the latest Docker container.
If you have a container with a different name, then you need to update the dockerfile and create a zip file again. Once you have done this, upload and deploy it to EB.
There you have it. A quick, but complete, Docker case study about deploying Docker containers on AWS Elastic Beanstalk.
Looking for more information on Docker? Many organizations are extending Docker containers to support a microservices strategy. For more information in microservices on AWS, see this link.
Get Started with AWS
Receive AWS tips, DevOps best practices, news analysis, commentary and more. Sign up for our IT Modernization blog here and set your topic and frequency preferences. Or, download our guide on getting started with AWS, establishing a secure AWS enterprise architecture with Flux7 Landing Zones.