This guide is a very slight, helpful repackaging of Arik Liber's Medium article on running Node on AWS Fargate.
Overall, this repo depends on Serverless Framework and the plugin serverless-fargate-plugin, whose base configuration is what's used here.
For the application, we first need a small application that listens to requests. A tiny app using Fastify as a server is provided. Then that app needs to be packaged into a container image, and put on a container registry. Such a Dockerfile is also provided. For this example we will put the image on AWS Elastic Container Registry.
- You have Docker working on your system, else read this guide or just use Docker Desktop
- You have an AWS account or an IAM/SSO user in an AWS account
- You have credentials to create (et cetera) Fargate instances and any required resources such as VPCs and security groups
- Edit the placeholders in
build-and-push-docker-image.shto correspond with your settings - Edit the placeholders in
serverless.ymlto correspond with your settings - If you have a container image: Run
npm run startoryarn startto both build, push, and deploy (deployment requires that you provide the full path to the container image) - If you don't already have a container image: Run
npm run buildoryarn build; go to ECR (web GUI or CLI) and create a new repository; grab the image URI; use the image URI inserverless.ymlto specify image location; then deploy withnpm run deployoryarn deploy - If all goes well and you've deployed with Serverless Framework you can follow the steps under "Setup up Fargate, method 1: Use Serverless Framework" to see how to get your URL
Steps that will be done:
- You will need to have a Docker image of your own (or know the ARN of one); a tiny Node application is provided in this repo so you can build one of your own
- You need to get Fargate up and running with that image, either manually or with the help of Serverless Framework
We will run the default ECR steps to login and push. Of course all of this works with Dockerhub or something similar as well, but I'm sticking to the AWS specific services for this context.
$(aws ecr get-login --no-include-email --region {REGION})docker build -t {PROJECT_NAME} .docker tag {PROJECT_NAME}:latest {ACCOUNT_NUMBER}.dkr.ecr.{REGION}.amazonaws.com/{PROJECT_NAME}:latestdocker push {ACCOUNT_NUMBER}.dkr.ecr.{REGION}.amazonaws.com/{PROJECT_NAME}:latest
An included shell script (build-and-push-docker-image.sh) runs those commands and a couple of extra helper lines get dependencies, login and build all from the comfort of the root directory.
- Edit
build-and-push-docker-image.shto contain your configuration (account number, region etc.) - Deploy by running
yarn deployornpm run deploy; this will take a few minutes - When it's done, go to https://us-east-1.console.aws.amazon.com/ec2/v2/ (note: this path obviously assumes
us-east-1region) - Under the "LOAD BALANCING" category, click "Load Balancers"
- There should be a load balancer up, click on it
- In the bottom panel, under "Basic configuration" there should be a DNS name, such as
serve-ECSLo-1HXFYPJLNQHP7-794422707.us-east-1.elb.amazonaws.com– that's your URL! - Visit the URL and it should show 'Hello world'
Something that should be obvious, but probably is not, is that regular ECS (based on "serverful" EC2 instances) will likely work in any region, but Fargate (as I learned the dull and hard way) is not available exactly everywhere. There should be a choice called "Networking Only" or similar, which is the Fargate option. That's how you see that your region supports it. If you just want to test things out, go for North Virginia (us-east-1).
For now, I will simply point you (again) to the excellent article by Arik Liber on Medium. This is definitely clear enough to give you the steps, with images and all.
NOTE: Based on my Docker image and current config, I needed to add :8080 to the URL when doing everything the vanilla way and without the load balancer. This is not ideal and would require some change that I've been too lazy to fix yet. Try both with and without the :8080 added after the URL.