Use multiple Docker images on the same ECS service

Use multiple Docker images on the same ECS service

Node.js app linked to Prometheus app using Docker and ECS

Video version: youtu.be/-rOUt7IDV8I

In this article, we’ll explore how to use the event monitoring and alerting system Prometheus with a Dockerized application running on Amazon Elastic Container Service (ECS). We’ll use the following technologies:

  • A Node.js application (based on the official TinyStacks repository)
  • A Prometheus application (also available as a TinyStacks repo)
  • Docker to create images from both of the applications
  • Amazon Web Services ECS (Elastic Container Service)

Here’s what you’ll need

Git, Docker, and the AWS CLI installed locally An active AWS account

Not familiar with Docker? Check out my article and video on launching a simple Hello World Express app with Docker for everything you need to know!

Node.js

Node is a back-end JavaScript runtime environment. It executes JavaScript code on a computer, such as your dev desktop or a Web server.

The good news is that, because you have Docker, you don't actually need to install Node.js. In this walkthrough, we’ll use the Node container image for Docker. This ensures that we avoid version conflicts between the version of Node installed on my machine and yours. It also prevents conflicts during the evolution of the application in production.

Prometheus

Prometheus is a free software application used for event monitoring and alerting. It records real-time metrics in a time series database built using a HTTP pull model, with flexible queries and real-time alerting.

Steps

Here’s what we’ll be doing today to achieve our goal:

  • Clone the aws-docker-template-express GitHub Repositorygithub.com/gaiaslastlaugh/aws-docker-templa.. and switch branches
  • Build the Node.js image with Docker
  • Create an ECR repository for our Node.js App
  • Tag and push the Node.js app image
  • Create the Node.js service using ECS
  • Test the Node.js application
  • Clone the node-express-monitoring repository and add Node.js IP in the target
  • Build the Prometheus image with Docker
  • Create ECR repository for the Prometheus App
  • Tag Prometheus image and push it to ECR
  • ECS add task definition for service 2
  • Change security group inbound rules
  • Final Test

Clone aws-docker-template-express GitHub Repository

Go to the AWS Docker Template for Express and clone it from your command line:

git clone https://github.com/tinystacks/aws-docker-templates-express.git

Change into the directory:

cd aws-docker-templates-express

Create a new branch:

git checkout -b prometheus-integration

Open the folder using your favorite IDE. If you use Visual Studio Code, you can type

code .

Our branch now contains the Prometheus client.

Build the Node.js Image with Docker

Now let’s build our Docker image.

docker build -t nodejs-app .


docker images

image.png

Create ECR repository for Node.js App

Now let's create an ECR (Elastic Container Registry) repository on AWS to store the images we built. We can easily do this using the AWS CLI. If you need to set up the AWS CLI, check out my instructions in this article.

aws ecr create-repository --repository-name nodejs-app --region us-east-1

Let's check on the AWS Console if the repository has been created correctly:

image.png

If you see something like this, you’re good to go.

image.png

Tag and Push the Node.js app Image

Now let's tag the image using the following command, replacing <ECR_REPO> with your ECR repository URI:

docker tag nodejs-app <ECR_REPO>

Now you can push the image to the existing ECR repository:

docker push <NODEJS_IMAGE>

Create the Node.js Service Using ECS

On the AWS Console, look for ECS (Elastic Container Service):

image.png

Let's create a new task. On Container Definition, click Custom:

image.png

Here we just need to define 3 things:

  • Container name: use nodejs-app
  • Image: The image in the ECR repository
  • Port: 8080

Container name and image:

image.png

Port mapping:

image.png

For this next step and for the service definition, you can click Next.

For the cluster, you can define a custom name - for example, prom-node:

image.png

Click Next,Finally, click Create:

image.png

Now we need to wait a couple of minutes, until the cluster, the service, and the task are up and running.

image.png

Go to Tasks and wait until the status is Running (green):

image.png

Click on the task (not the task definition) and copy the IP address:

image.png

Test the Node.js Application

Go on any browser and visit NODEJS_APP_IP:8080/metrics, where NODEJS_APP_IP is the IP we just copied. You’ll see something like this:

image.png

Clone the node-express-monitoring Repository

Now let's clone the second repository:

git clone https://github.com/tinystacks/node-express-monitoring.git

Change into the directory:

cd node-express-monitoring

Open the folder with your favorite IDE. For example, if you use Visual Studio Code, type:

code .

Open the prometheus folder. Next, open the prometheus.tml file and replace nodejs-app` with the IP address of your application:

image.png

(Note: this is just for demo purposes, not production-ready, as the IP address should be dynamic!)

Build the Prometheus Image with Docker

docker build -t prom .

Create an ECR Repository for Prometheus

aws ecr create-repository --repository-name prom --region us-east-1

Tag Your Prometheus Image and Push to ECR

Let's tag the built image with the new repository. Replace <ECR_REPO> with your ECR repository URI:

docker tag prom <ECR_REPO>

Now you can push this image to the ECR repository:

docker push <PROMETHEUS_IMAGE>

dd Task Definition in ECS for Second Service

On ECS, in the same cluster, create a new task definition for the Prometheus image:

image.png

Select FARGATE and click "Next Step"

image.png

Configure your task and container definitions, adding the task definition name and the task role as below:

image.png

Define Memory and CPU (you can use the lowest ones)

image.png

Finally, click Add container:

image.png

Add the container name and the URL to the container image (note that I’ve whited out the AWS account ID in this image for security purposes):

image.png

For port, use 9090, the default port of the official Prometheus image:

image.png

Leave everything else as it is, and click *Add

In Clusters, click on the cluster's name (in our example, prom-node)

image.png

Next, click on Run New Task:

image.png

In Run Task, define:

  • LaunchType: Fargate
  • Task definition: prom (or the name you have defined)

image.png

Define a subnet:

image.png

Then click on Run Task:

image.png

Go on the cluster again and you will see two running tasks (wait for the one you just defined to transition to RUNNING):

image.png

Change Security Group Inbound Rules

Before the final test, be sure that the inbound rules of this task are set up properly. Click on the ENI ID:

image.png

On the Network interface, click on the security group:

image.png

Click on Edit Inbound Rules and ensure that this task is accessible from the outside:

image.png

Final Test

Visit the public IP address of the second service we deployed (the Prometheus one):

image.png

As you can see, the Prometheus application is linked to the Node.js app deployed on the Node.js app IP address. Success!