Deploy A Full Stack JavaScript Application With Amazon ECS and Docker

Deploy A Full Stack JavaScript Application With Amazon ECS and Docker

Hello! In this guide, we will be walking through the process of deploying a full-stack application that has a database on Amazon ECS.

What is Amazon ECS? You may ask, ECS stands for Elastic Container Service. It is Amazon's container orchestration service used for deploying containerized applications and manages the process of creating, destroying, restarting, auto-scaling, and updating your containers. ECS can be used with EC2 instances where you are responsible for managing the underlying servers or serverlessly with Fargate where AWS will be responsible for provisioning and managing the underlying servers. We'll go with the serverless option in this guide as it is much easier to set up.

Objectives

The goal is to deploy a docker application on ECS that will be running behind an application load balancer and also use Amazon EFS to persist the data from our database. Here is a quick rundown of all the steps:

  • Create the fundamental resources i.e. Security Groups, Load Balancer, EFS Volume.

  • Create an ECS Cluster to deploy the application.

  • Create the Task Definition that contains the instructions necessary to run the application.

  • Starting a new service

N:B I am using the default VPC for this demo to keep things simple, but feel free to use a custom VPC if that's what you prefer.

1) Setting up the Security Groups, Load Balancer, and EFS Volume

In this step, we are focused on creating the resources which will later on be used by our docker application.

i) Security Groups

We will need 3 security groups in total; one for the application load balancer, the EFS volume, and the ECS task itself. Ensure that all these security groups are created in the VPC where your application will be deployed to. To create the security groups, you can navigate to the EC2 dashboard and you will find Security Groups in the left pane under "Network & Security"

  • First, create the Security Group for the Application Load Balancer with HTTP and HTTPS inbound traffic and the source should be the public internet aka 0.0.0.0.

  • Secondly, create the ECS task security group which should have HTTP and HTTPS inbound traffic and the source is the Application Load Balancer security group.

  • Finally, create the EFS security group with NFS inbound traffic from the ECS task security group.

ii) Application Load Balancer

Still in the same EC2 dashboard, we can find the option to create the load balancer in the left pane under "Load Balancing". Before creating the load balancer, we need to create the target group for the load balancer. Create the target group with the following options:

  • In the target type, instead of the default option "instances", select "IP addresses".

  • Under VPC, you can select your custom VPC or leave it as the default.

  • Also, give your target group a name and Create the target group.

Now go ahead and create the application load balancer with these settings:

  • Type - Application Load Balancer.

  • VPC - Select your custom VPC and subnets or leave it as default.

  • Security Group - Select the security group we created earlier for the ALB.

  • Listener - Choose the Target Group we just created.

iii) EFS

In your AWS console, search for EFS and Navigate the EFS Dashboard. Create a new EFS Volume with these options:

  • VPC - leave it to the default or select the one you created.

  • Assign the EFS Security Group that we created earlier to it.

  • All the other settings can be left as default.

2) Creating an ECS Cluster

Creating an ECS cluster is straightforward, all you need to do is:

  • Navigate to the ECS dashboard on the AWS console and click on "Create cluster".

  • Give it a name and select your VPC & Subnets then create the cluster.

3) Creating the Task Definition

Now here comes the tricky part, creating the task definition. In the ECS dashboard, click on "Task definitions" in the left pane and create a new Task Definition. In the wizard, we have to create 3 containers; MongoDB (the database), the frontend, and the backend. These are the links to public docker images:

MongoDB: https://hub.docker.com/_/mongo

Frontend: https://hub.docker.com/r/ajimbong/vidly_front_prod

Backend: https://hub.docker.com/r/ajimbong/vidly_back_prod

First, let's start with configuring the Mongo Container with the following options:

  • Give it the name "mongo" and Image URI "mongo"

  • In port mappings, provide the "27017" port number. This is the default port for MongoDB.

Secondly, configure the backend container:

  • The name should be "backend" and Image URI "ajimbong/vidly_back_prod"

  • Set "3001" as the port mapping as this is the port the backend is listening on.

  • Create an environment variable with key "DB_URL" and value "mongodb://localhost:27017/vidly"

  • Scroll down to Startup dependency ordering and select the "mongo" container as a startup dependency.

Finally, create and configure the frontend container:

  • Give the name "frontend" and Image URI "ajimbong/vidly_front_prod".

  • Set port "80" as the port mapping.

  • Lastly, set the "backend" container as a Startup dependency.

The Containers are all set up and the last step now is to configure the storage.

  • Click next to navigate to the next page.

  • Under Storage click on "Add Volume" and select "EFS" as the volume type.

  • Give the Volume a name and select the filesystem we created earlier under "File system ID".

  • Scroll Down and click on "Add mount point".

  • In the mount point, select the "mongo" container and specify the Container path to "/data/db". This is where MongoDB stores its data by default.

  • These are all the settings we need, so now you can create the task definition.

4) Starting a Service From the Task Definition

The last and final step is to start a service from our task definition and see if everything works properly.

  • Go to clusters and select the cluster we created earlier.

  • Under Services, click on Create.

  • In "Family", select the task definition we created in the previous step.

  • Give the service a name and set the desired instances to "1".

  • Expand the "Networking" drop-down and select your VPC and subnets.

  • Also, select the ECS security group we created earlier.

  • Expand the Load balancing dropdown and select "Application Load Balancer".

  • Select use an existing load balancer and choose the one we created earlier.

  • Also, select use and existing listener and choose the listener with port "80".

  • Again, select the use and existing target group and choose the one that was created earlier.

  • Finally, we create the service and wait for AWS to provision the resources.

If everything works out well, you should be able to copy the public DNS of the application load balancer and test it in the browser.