Step by Step guide to Dockerize webapp and run containers in AWS ECS
1. Local Implementation
Step 1 : Develop the Machine Learning / Deep Learning Model Locally and prepare an Inference script (app.py)as illustrated below:
run the app locally :
streamlit run app.py
Step 2: Dockerize Streamlit webapp
1. Build the App
2. Run the inference App locally
3. Create A Dockerfile
4. Build the Docker Image
5. Run the App in Docker
Sample Dockerfile used as a sample for the problem statement I have used
A Dockerfile is a file that contains instructions on what and how to build a docker image. This is an automated process that operate by building the images based on layer or steps hence order is very important in creating a dockerfile. The name of the file must be Dockerfile without any extension.
The basic set of instructions for any dockerfile include the following :
FROM <image>: this is from where you want to build the base image or operating system.RUN <command>: this command tells the docker daemon to run a set of commands or programs either via
1. shell form : RUN pip install -r requirements.txt
2. the exec form: RUN ["pip","install","-r","requirements.txt"]WORKDIR <directory>: this shows the working directory we will be setting up within our imageENTRYPOINT [commands] : Allows for configuring the container as an executable. The entrypoint is similar to the CMD in that they serve as a point for what command to run in the container not the image, but rather when you create a container from an image.CMD <commands>: this is used to provide defaults for an executing container. You can use the shell form or the exec form . When you use both together it is recommended to use it in the exec form that follows the JSON array format.EXPOSE <port>: This informs Docker that the container is exposed to listen on the specified port at runtime.COPY <source> <destination> :For copying files from one place to the image.
Build the image
To build the image we can run the below command
docker build -t <imagename and tagname> .
We can also use a -f option if we do not want to look for the dockerfile in the current directory or context.
docker build -t <imagename and tagname> -f Dockerfile
This will build a docker image with the name specified and will contain all the necessary requirement to run the app.
Check for the docker images
docker images ls
We can also check for the history of the images using the below command
docker history <imagename>
Run the containerized app
To run the app we can then create a container from the image which will behave like a mini computer with everything that is required to run the app as if we were running it on your local system.
docker run -p 8501:8501 <imagename>:latest
We can then navigate to the url in our browser using the external network url.
Using Docker Desktop for windows
2. Publish a Docker Image from a local machine to AWS Cloud
Step 1: Install the AWS Command Interface on windows using the following link.
Step 2: After installing the AWS CLI in Linux, configure the AWS from your terminal using the command.
To get the AWS Access Key ID and Secret Access Key, go to your AWS console and click My Security Credentials -> Access keys (access key ID and secret access key) -> Create New Access Key. Give your region name and give the default output format empty and type enter which will set the output format to default.
Step 3: Create a repository in AWS ECR
Amazon Elastic Container Registry (ECR) is a fully managed container registry that makes it easy to store, manage, share, and deploy your container images and artifacts anywhere.
Create a ECR repository using link using aws cli
2.3.1 Create an Amazon ECR repository to store your
streamlitapp image. Note the
repositoryUri in the output. Substitute
region, with your AWS Region, for example,
2.3.2 Tag your image so you can push the image to this repository:
docker tag streamlitapp:latest 496747191055.dkr.ecr.us-east-1.amazonaws.com/streamlitapp-repository
image name = streamlitapp:latest
aws_account_id = 496747191055
repositoryUri = streamlitapp-repository
2.3.3 Run the aws ecr get-login-password command. Specify the registry URI you want to authenticate to. On success ‘Login Succeeded’ message will be shown.
aws ecr get-login-password | docker login — username AWS — password-stdin 496747191055.dkr.ecr.us-east-1.amazonaws.com
2.3.4 Push the image to Amazon ECR with the
repositoryUri value from the earlier step. Run the following command to push this image to your newly created AWS repository:
docker push 496747191055.dkr.ecr.us-east-1.amazonaws.com/streamlitap p-repoistory
On success, it will be seen in the repo as below.
3. Pull the Docker Image and run the container in AWS ECS
Elastic Container Service
Amazon ECS makes it easy to deploy, manage, and scale Docker containers running applications, services, and batch processes. Amazon ECS places containers across your cluster based on your resource needs and is integrated with familiar features like Elastic Load Balancing, EC2 security groups, EBS volumes and IAM roles.
Choose an image for your container to get started quickly or define the container image to use.
A task definition is a blueprint for your application, and describes one or more containers through attributes. Some attributes are configured at the task level but the majority of attributes are configured per container
Define your service
A service allows you to run and maintain a specified number of simultaneous instances of a task definition in an ECS cluster.
Configure your cluster
The infrastructure in a Fargate cluster is fully managed by AWS. Here containers run without you managing and configuring individual Amazon EC2 instances.
Review the configuration you’ve set up before creating your task definition, service, and cluster.
3.1 Creating ECS Cluster
3.1.1 Go to Amazon ECS and click on “get started”. The below landing page is presented
3.1.2 Select create cluster and choose networking only option because we do not want to manage any servers. Then click on “next step”
3.1.3 Choose a name for your cluster and select create VPC as well. None of these resources cost anything until we run a task. Then click on “Create”
3.1.4 Once the cluster is created successfully, we can click on view cluster to see that there are no tasks running yet
3.2 Creating ECS Task Definition
In task definition we describe which containers will be running in our task.It is a good practice to have only one container in a task but we can optionally have many depending on the use case.
3.2.1 Got to Task definitions then create new task definition and choose FARGATE and click on Next Step
In task definition menu do the following:
· Name your task definition
· Task role does not concern us as we will not be communicating with other AWS services
· If our app was a real life project, we would most likely to attach some IAM policies to a role and assign it
· For OS family choose Linux and set RAM and CPU to minimal values as it involves cost
· Click on add container (add our containerized image)
· Make sure set the correct port mapping
3.2.2 Configure task and container definitions. Specify a name for the task definition. Choose OS as Linux, followed by Task memory and CPU
3.2.3 specify the repositoryUri details from the ECR while we had created the container registry as the image name
Click on add and the below landing page is presented
Click on the Create button, the task definition is being created
3.3 Creating and Running ECS Task
In ECS Cluster home page go to tasks tab and click on run new task
Steps to follow : -
· Select Launch Type as FARGATE (AWS FARGATE is a server-less approach)
· Operating System as Linux
· We need to select at least one subnet and since we have not provisioned any load balancer or reverse proxy make sure to select public subnet . This will make sure that tasks get assigned a public IP so that we can access it from the internet
· Make sure that the Auto Assign Public IP is enabled
· Edit the security group to add Custom TCP with port number as 8051 which is specified in our task in order to allow the webapp to be accessed from anywhere
· Click on run task
Note: AWS- Fargate is a server less approach which means AWS will run the containers on servers which we do not have to worry about maintaining. Fargate is available for both ECS and EKS
3.3.1 click on run new task
3.3.2 Select launch type as FARGATE. We need to select at least one subnet, and since we haven’t provisioned any load balancer or reverse proxy, make sure that it is a public subnet. A public subnet will make sure that this task gets assigned a public IP, meaning we can access it from the internet
3.3.3. We need to create a security group. A security group is basically an instance level firewall (or task level, in the case of Fargate), which blocks traffic on all ports if not specified otherwise. This is important because if you don’t enable TCP traffic on port 8501 (which is the port we specified in our task definition), then it will be impossible to access this web app from anywhere. Finally, we nee to make sure that the Auto-assign public IP setting it set to enabled.
3.3.4 Click on save and run the task
3.3.5 Once the last status filed is set to running copy the public IP
3.3.6 Paste the public ip along with port number in the browser : 188.8.131.52:8501 the streamlit app Screen is prompted as illustrated below
Everything worked successfully !!!
4.1 In order to not get charged for our example simply delete the registry and the cluster in the menu of our cluster .
When you are done experimenting with your Amazon ECR image, you can delete the repository so you are not charged for image storage. Run the below command in AWS CLI
aws ecr delete-repository — repository-name streamlitapp-repository — region us-east-1 –force
4.2 Stop the task running
4.3 Deregister task definition
4.4 Delete the cluster
Note : In order to delete an empty cluster from AWS CLI run the below command
aws ecs delete-cluster — cluster <name of the cluster>
Knowing how to run containers in the cloud is a very important skill for any developer. Hope the above steps help in containerizing a web app and runing in AWS ECS.