How to Setup Node.JS Web Server to AWS with ECS
Table of Contents
- Introduction
- Requirements
- Create Simple Node.js App
- Build Node.js as Docker Image Locally
- Verify Local Node.js Web Server
- Create Image at AWS ECR
- Push Docker Image to AWS ECR
- Create ECS Cluster
- Create Task Definitions
- Create Task at Cluster
- Delete Resources
- Conclusion
Introduction
This blog will focus on how to create a simple Node.js app using Docker, then push the Docker image to AWS ECR and ECS and use AWS Fargate to serve this Node.js web server.
Requirements
- AWS Account — first of all, you'll need an AWS account. If you don't have one already, you can create one and get an AWS free tier for a year.
- Basic knowledge about AWS, Node.js, Docker, creating images and containers, ECR, ECS, and Fargate.
Create Simple Node.js App
First, we'll create a simple Node.js web application and build an image using Docker. Here, we'll start creating the Node.js application by running the commands below.
npm init -y
npm install express --save
nano app.js
The first command initializes a npm package.json file with npm init -y, then installs the only dependency, which is express. Run nano app.js or create a file manually with the name app.js, then add the following content to app.js.
const express = require('express')
const app = express()
app.get('/', (req, res) => {
res.send('hello world!')
})
app.listen(7777, () => {
console.log('server is up on 7777')
});
This code starts a web server using express and returns hello world! when a GET request is made on port 7777.
You can test the page by typing node app.js in the command console.
Build Node.js as Docker Image Locally
In this section, we'll build a Docker image and create a container.
Create a Dockerfile in the same directory and add the following content.
FROM node:8-alpine
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY . .
RUN npm install
EXPOSE 7777
CMD ["node", "app.js"]
Now, let's run this command to build the Docker image. This will build the image and store it locally.
docker build -t sample-docker-nodejs-app .
Once the Docker image build succeeds, you can run this to list the images and verify the image we just created.
docker images

Now, run the Docker container with the image we just built. This tells Docker to use the image 1722c9508798.
docker run -p 3300:7777 1722c9508798
Verify Local Node.js Web Server
Type the URL http://localhost:3300 below to see if you can get a response from the containerized Node.js app. If we get hello world!, it means the Docker image/container works locally and is ready to be set up on AWS.
curl http://localhost:3300
Create Image at AWS ECR
So far, we've created a Docker image locally, then used the image to create a container and exposed port 7777 to the caller as 3300. We'll do the same in the cloud with AWS. First, we need to create a Docker image repository in AWS — that'll be ECR (Amazon Elastic Container Registry), where we can push our image. You can set the image as either public or private.
In this section, we'll create a private repository for our Docker images.
First, go to the AWS console, navigate to ECR, and click Create repository. Choose Private for the visibility. For the name, I'll create it as shown below. We choose immutability as Enabled. There are a few more settings here, but for this blog, this will be enough.

Once you've selected everything, click Create repository. If the repository is created successfully, you should see your image as shown below.

aws ecr create-repository --repository-name my-sample-docker-nodejs-app --image-tag-mutability IMMUTABLE
Push Docker Image to AWS ECR
Once the AWS ECR repository is created, click into it and you won't see any images yet, as shown below.
Here we'll push our Docker image.

AWS ECR already has a list of commands to help push images. Click View push commands and you should see the details of how to use the AWS CLI to push a local image to ECR.
First, run the command below to authenticate. Once successful, you should see Login Succeeded.
aws ecr get-login-password --region us-west-1 | docker login --username AWS --password-stdin {your account id}.dkr.ecr.us-west-1.amazonaws.com
Second, build the Docker image. If you've already built the image locally, you can skip this part.
docker build -t my-sample-docker-nodejs-app .
Next, tag the image with the ECR repository.
This will return the AWS account ID.
aws sts get-caller-identity
docker tag my-sample-docker-nodejs-app:latest {account id}.dkr.ecr.us-west-1.amazonaws.com/my-sample-docker-nodejs-app:latest
Lastly, push the image to AWS ECR.
docker push {account id}.dkr.ecr.us-west-1.amazonaws.com/my-sample-docker-nodejs-app:latest
Once the image is pushed successfully, you should see the new record here.

Create ECS Cluster
We're close to finishing. So far we have our Docker image in ECR, which exposes port 7777. From here, we'll create clusters and tasks to run the Docker image.
Click Create Cluster and choose Networking Only.

During cluster configuration, enter any name for the cluster. If you already have a VPC, you can skip that step, or create a new VPC as shown below.

Once the cluster is created, you should see this screen confirming that the ECS cluster and CloudFormation Stack have been created.

aws ecs create-cluster --cluster-name my-cluster
Create Task Definitions
After creating an ECS Cluster, we'll create a new task definition. Choose Fargate.

When creating a new task definition, most of the fields can be kept as default. One important thing is that we'll add the container and choose the image we pushed from our local machine to the ECR repository.


Create Task at Cluster
After creating the cluster with our container from ECR, we'll create a task so our app will run. Go to the cluster, choose the one we just created, and click create task.

Once a task is created for the cluster, AWS should start building the container and create a public IP address. For testing, you can copy the Public IP address below and test it in the browser.

One thing to remember is that you need to add port 7777 to the security group's inbound rules. Once you add port 7777, type the URL below in the browser.
If everything works, the browser should return the same response as from our local environment.
http://54.183.190.94:7777
That's all we need to cover for this blog. Next is deleting the resources to avoid unexpected charges.

Delete Resources
If you created ECR, Fargate, and the cluster just for testing, you need to delete these resources once your testing is done.
DeRegister Task Definition

Delete Clusters

Conclusion
The above covers how to deploy a simple Node.js app to AWS ECS with Fargate. This blog covered how to set up Node.js, build and run an image/container locally, and how to build and run an image/container on AWS. Next, you could try using a different language, a different compute option, or try to automate this process.