AWS Fargate: From Start to Finish for a NodeJS App

Arik Liber
8 min readJul 14, 2018

--

This is going to be a very visual walkthrough of “Dockerizing” a NodeJS app and deploying it on top of AWS Fargate.

The walkthrough is going to be broken into 7 sections:

  1. Dockerizing our app
  2. Hosting our Docker image
  3. Creating an ECS task definition
  4. Configuring a cluster
  5. Creating a Load Balancer (optional)
  6. Creating our service
  7. Configuring our domain (optional)

Plenty of material, lets start!

What is AWS Fargate?

You can find the formal explanation here (and in many other tutorials around) but simply put: Fargate is a way for you to avoid messing around with EC2 instances, running Docker deamons, managing versions and Devops in general.

Basically, Fargate runs a Docker container for you and manages the infrastructure — so you don’t have to.

Fargate v.s. Lambda

Lambda can run specific functions and theoretically can serve as a backend for an app, however, if you already have a NodeJS app (possibly with Express) — migrating it to Lambda is a pain (although there are some packages that can help you with that). Enter Fargate — a way to avoid both server management (i.e. “Serverless”) and the refactoring of your app for Lambda, allowing you to deploy your existing app fairly quickly.

A final note before we start

The explanations are simplified, I’m also not an expert so I’m sure some steps could be explained better — I would love to hear your thoughts and suggestions in the comments. Writing this is a way for me to document the process and to improve following your suggestions — so thank you 🙏🏼

Step 1/7: Dockerizing our app

Assuming you already have a NodeJS app — let’s start by adding a Dockerfile to our repo:

I won’t go into details since this is pretty standard stuff apart from the CMD line: We’ll still need to run our NodeJS app (in my case an Express app) within the container. We could just run node index.js but that is a bad idea and would not recover after crashes etc. Instead, I’m using the awesome PM2 package to manage the process — it is already Docker ready.

To test it simply run `docker build -t webapp-backend .` and then `docker run -it -p 3000:3000 webapp-backend` (use your own ports of course). Going to http://localhost:3000 in your browser should show the app/API.

Step 2/7: Hosting our Docker image

Now that our NodeJS app is dockerized we need to host it somewhere before we can actually run it. Docker Hub is one such place but when it comes to AWS — the goto is AWS ECR. Start by creating a new repository:

Creating new repo in AWS ECR
Give it a name

In the final step, you’ll be provided with a list of commands you run to publish to that new repo. I created a scripts/deploy.sh file in my project so I have a one-liner to publish there. This is how my script looks:

Notice the | /bin/bash at the end which executes the proceeding command, which is in charge logging us in.

This works on Unix systems, Windows users might need to find a different way

Run the provided commands to publish your image to AWS ECR.

Step 3/7: Creating an ECS task definition

A task definition specifies the container information for your application.

Create a new Task Definition
Select “Fargate”

The next screen is about specifying the container we want to run, it’s resources and ports. To select the container we’ll be using — click “Add Container”:

Now let’s go back to ECR for a moment and find the unique address of our container image:

so we can use it in our task:

Specify task URI and application ports

The final thing you might want to do it is to specify the environment variables you app needs such as NODE_ENV and others:

Specifying environment variables

Step 4/7: Configuring a cluster

At that point you might feel a bit tired — we’ve configured and ECR, a task definition and now a cluster? don’t give up just yet. There are many more moving parts to it but I would argue that if you “master” a single compute stack — this should be it.

Anyway, a cluster is where our service instances will run — i.e. tasks. Let’s create one:

Click “Create Cluster”
Selecting our cluster template

In the next screen pick a name for your cluster, and choose whether or not you want to create a new VPC along with it (if you’re not sure what that means — leave it unselected — you already have a default one).

This is how it looks eventually:

Our new cluster!

Step 5/7: Creating a Load Balancer (optional)

We have a repository for our docker image, we have a task definition and even a cluster. The final piece of the “Fargate puzzle” is a service but before we create one — we’ll create an ALB (Application Load Balancer). This step is not mandatory as you can request a public IP address for your task but if you’ll be running a user-facing application — a load balancer is a must since the public IP will change very time you re-deploy your app.
A dedicated load balancer will also you to attach a domain to it your Fargate task.

Let’s head over to AWS EC2 and create our new load balancer:

Creating a new load balancer
Select “Application Load Balancer”

In the next screen, you’ll have a chance to select your HTTPS certificate. If you don’t have one yet — you can request a free certificate from AWS ACM. I have one so I’m selecting it:

next let’s configure our ports:

Security groups

In the next screen create a new target and don’t forget to configure a proper health check route — that’s a route that returns status 200 . It may be useful for that route to return an application version as well so you can quickly check what exactly is running.

The next and final screen is about defining targets but we’ll skip it as the target will be defined automatically once we deploy our task by Fargate.

Make sure everything is correct by looking at the summary page and click “Create”.

Step 6/7: Creating our service

Finally, we’ll create a service which is an instance of our task definition which will go into our cluster. Almost done!

Let’s head back to AWS ECS and create a new service:

Notice how we select the task definition we’ve created earlier and set the number of tasks (analogous to instances). I’ll go with 1 for this demo.

On the next screen click the “Edit” button next to “Security groups” to edit the security group and specify the desired ports of our app (3000 in my case):

Setting a security group

Click “Save” when done.

Under “Load balancing” select “Application Load Balancer” and select our newly created load balancer from the drop-down:

Selecting a load balancer

Then click on “Add to load balancer” button to apply the ports to the load balancer. Make sure to enter the health check path or the app won’t receive any traffic!

Everything else can be left as is.

Hit “Next step” for the rest of the wizard and we’re done!

If everything was correct the status will soon change to RUNNING.

To test the app, grab its public IP:

and head on to the health check route you entered previously:

Step 7/7: Configuring our domain (optional)

This step is the easiest: if you've followed along with certificate selection in step 5 — you also probably already have a domain.

If you don’t — AWS Route 53 is where you can buy domains and also link them to different resources, for example, a load balancer.

Head over to AWS Route 53 and select “Hosted zones”:

Select “Hosted zones”

Select a hosted zone from the list or create a new one, corresponding to a domain you own.

In the next screen you will:

  1. Create a new record set (which is our case is a subdomain)
  2. Name the subdomain
  3. Select “Alias” = “Yes”
  4. Select our ALB from the drop-down under “Alias Target”

In a couple of minutes, your domain will get tied to the ALB which is connected to our Fargate instance. Easy 😅

Conclusion

While there where many configurations, tweaks, and small caveats I didn’t dive into — these are all the most crucial steps necessary to start with Fargate. If you’re new to AWS and want to invest a minimum amount of Devops while also sleeping well at night — Fargate is a great option.

It may seem like there are a lot of steps involved but many of them as well as their core concepts are not unique to Fargate (such as AWS Route 53, ALB and more) thus one would have to master them anyway, regardless if you go for Fargate or not.

Feedback, questions and mostly corrections are welcome in the comments!

Happy deploying

--

--