step-by-step guide, along with sample code, for deploying a web application using containers. In this example, we’ll use Docker for containerization and Amazon ECS with Fargate for deployment. We will also push the Docker image to Amazon ECR (Elastic Container Registry).
Create a simple Node.js or Python web application as an example.
Node.js Example (app.js
):
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('Hello World from Docker!');
});
const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log(`App running on port ${port}`);
});
This file defines the environment and steps to build the Docker image.
# Use an official Node.js runtime as a parent image
FROM node:14
# Set the working directory inside the container
WORKDIR /usr/src/app
# Copy package.json and package-lock.json to install dependencies
COPY package*.json ./
# Install dependencies
RUN npm install
# Copy the rest of the application code to the container
COPY . .
# Expose the port your app runs on
EXPOSE 3000
# Command to run the application
CMD [ "node", "app.js" ]
Build the Docker image using the following command:
docker build -t my-web-app .
Run the Docker container to verify everything works:
docker run -p 3000:3000 my-web-app
Create a new ECR repository using the AWS Management Console or CLI:
aws ecr create-repository --repository-name my-web-app
Run the following command to authenticate Docker to your ECR registry (replace <aws-region>
with your region):
aws ecr get-login-password --region <aws-region> | docker login --username AWS --password-stdin <account-id>.dkr.ecr.<aws-region>.amazonaws.com
Tag your Docker image to match the ECR repository URI:
docker tag my-web-app:latest <account-id>.dkr.ecr.<aws-region>.amazonaws.com/my-web-app:latest
Push the image to ECR:
docker push <account-id>.dkr.ecr.<aws-region>.amazonaws.com/my-web-app:latest
Create an ECS cluster that uses Fargate as the launch type:
aws ecs create-cluster --cluster-name my-ecs-cluster
Create an ECS task definition that specifies the Docker container image, memory, CPU, and networking details.
Sample ECS Task Definition (task-def.json
):
{
"family": "my-web-app-task",
"networkMode": "awsvpc",
"executionRoleArn": "arn:aws:iam::<account-id>:role/ecsTaskExecutionRole",
"containerDefinitions": [
{
"name": "my-web-app",
"image": "<account-id>.dkr.ecr.<aws-region>.amazonaws.com/my-web-app:latest",
"portMappings": [
{
"containerPort": 3000,
"protocol": "tcp"
}
],
"essential": true
}
],
"requiresCompatibilities": [ "FARGATE" ],
"cpu": "256",
"memory": "512"
}
Register the task definition:
aws ecs register-task-definition --cli-input-json file://task-def.json
Create an ECS service to run the task continuously. This service will run on the ECS cluster using Fargate.
aws ecs create-service \
--cluster my-ecs-cluster \
--service-name my-web-app-service \
--task-definition my-web-app-task \
--desired-count 2 \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[subnet-xyz],securityGroups=[sg-xyz],assignPublicIp=ENABLED}"
Make sure to replace subnet-xyz
and sg-xyz
with the appropriate subnet and security group IDs in your AWS VPC.
To expose your application publicly, you might want to set up an Application Load Balancer (ALB). Here’s how:
Create a load balancer in the same VPC and subnets as your ECS service.
Create a target group for your ECS tasks.
aws elbv2 create-target-group \
--name my-web-app-targets \
--protocol HTTP \
--port 3000 \
--vpc-id <vpc-id>
Update your ECS service to register tasks with the target group:
aws ecs update-service \
--cluster my-ecs-cluster \
--service my-web-app-service \
--load-balancers targetGroupArn=<target-group-arn>,containerName=my-web-app,containerPort=3000
Set up CloudWatch alarms to monitor CPU or memory usage. When an alarm is triggered, you can scale the number of ECS tasks automatically.
Enable ECS Service Auto Scaling by creating scaling policies that trigger based on CloudWatch metrics (like CPU utilization).
aws application-autoscaling register-scalable-target \
--service-namespace ecs \
--resource-id service/my-ecs-cluster/my-web-app-service \
--scalable-dimension ecs:service:DesiredCount \
--min-capacity 1 \
--max-capacity 5
aws application-autoscaling put-scaling-policy \
--service-namespace ecs \
--scalable-dimension ecs:service:DesiredCount \
--resource-id service/my-ecs-cluster/my-web-app-service \
--policy-name my-scale-out-policy \
--policy-type TargetTrackingScaling \
--target-tracking-scaling-policy-configuration file://scaling-policy.json
To automate future deployments, set up a CI/CD pipeline using tools like AWS CodePipeline or Jenkins to automatically push new versions of the Docker image to ECR and update your ECS service.
This workflow allows you to deploy a web application using containers, push the image to ECR, and run the app on ECS using Fargate. You can also integrate auto-scaling and monitoring through CloudWatch.
Let me know if you need additional guidance on any specific step!