Deploying a Node.js Application using Docker: Three Effective Ways, including AWS ECS Deployment

Lidor Ettinger
Level Up Coding
Published in
3 min readMay 16, 2023

--

In this post, we’ll guide you through different methods of deploying a Node.js application and share the considerations we made along the way. We’ll cover the following approaches:

  1. Building a secure ‘Hello World’ Docker image.
  2. Using Docker Compose to create a scalable deployment that utilizes NGINX.
  3. Deploying the Docker image we previously created on AWS using Amazon Elastic Container Service (ECS).

By the end of this post, you’ll have a better understanding of how to deploy a Node.js application using Docker and AWS, and the benefits and trade-offs of each approach.

Throughout the post, we will focus on ensuring scalability and paying attention to security concerns

1. Creating a Docker Image of the Application

To help illustrate the process, we’ll be using the ‘Hello World’ Node.js application as an example. You can find more information about this application in the following resource.

Execute the following set of commands:

# Export the AWS account
export AWS_ACCOUNT_ID=<AWS_ACCOUNT>

# Clone the repository
git clone git@github.com:naturalett/nodejs-app.git
cd nodejs-app/web

# Build the image
docker build --tag ${AWS_ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/node-web-app .

# Run the image
docker run --memory="20m" --cpus="0.1" \
--name node-web-app \
-d -p 8080:8080 \
${AWS_ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/node-web-app

# Check the healthcheck
curl -i localhost:8080

# Stop the container
docker stop node-web-app

Here are the decisions we made while building the application

➜ Setting up a non-root user in your Dockerfile

Running containers as a non-root helps to mitigate security vulnerabilities. It also prevents malicious content from accessing the host container. We will setup a dedicated user or group identifier with only the access permissions your application needs. Then add the USER Dockerfile directive to specify this user or group for running commands in the image build and container runtime processes.

➜ Configure resource quotas

This feature enhances container security and makes them perform at an expected speed. If one container got infected with malicious code, it won’t let in many resources in as the quota cut it off. This further helps to minimize attacks.

➜ Keep images clean

Make sure that images downloaded from online platforms are from trusted and secure sources.

2. Running the Application using Docker Compose

Here we are going to use a docker-compose to orchestrate multi-container deployments. This lets us define multiple service within a unified configuration.

Execute the following set of commands:

# Clone the repository
git clone git@github.com:naturalett/nodejs-app.git
cd nodejs-app

# Build and deploy the stack
docker-compose up -d

# Check the healthcheck
curl -i localhost:80

# Stop the stack
docker-compose down

Here are the decisions we made while building the application

➜ Configure resource quotas

This feature enhances container security and makes them perform at an expected speed. If one container got infected with malicious code, it won’t let in many resources in as the quota cut it off. This further helps to minimize attacks.

3. Deploying the Docker Image on AWS using Elastic Container Service (ECS)

Here we will deploy our stack with Terraform in AWS.

Execute the following set of commands:

# Export the AWS account
export AWS_ACCOUNT_ID=<AWS_ACCOUNT>

# Clone the repository
git clone git@github.com:naturalett/nodejs-app.git
cd nodejs-app/terraform

# You need to build the image that we describe in step 1

# Login to ECR
aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin ${AWS_ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com

# Push the image to ECR
docker push ${AWS_ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/node-web-app:latest

# Initialization
terraform init

# Launch the stack
terraform apply

# Destroy the stack
terraform destroy

After completing the terraform deployment, you should log in to your AWS account, go to the Load Balancer, and access your application using the load balancer URL.

Summary

We were able to deploy a Node.js application on AWS using Terraform by making some crucial decisions during the process. Our approach involved building a secure Docker image of the application, using Docker Compose for scalability, and deploying the image on AWS Elastic Container Service (ECS).

Are you looking to enhance your DevOps skills and learn how to implement continuous integration using Jenkins container pipelines? Join my course, where you’ll gain practical experience in various pipeline scenarios and master production skills. Take the first step towards becoming a DevOps expert today.

Hands-On Mastering DevOps — CI and Jenkins Container Pipelines

--

--