Manually deploying NestJS ( or NodeJS) applications can be time-consuming and error-prone. Fortunately, AWS ECS offers a scalable and automated solution for deploying and managing containerized applications. This guide delves into the process of creating a buildspec.yml
file to streamline the deployment with AWS ECS with buildspec.yml
Prerequisites
Before diving in, ensure you have the following. Thease are important for deployment with AWS ECS:
- An active AWS account with appropriate permissions.
- A well-developed NestJS ( or NodeJS) application.
- Docker installed on your development machine.
- A basic understanding of AWS ECS and CI/CD concepts.
Understanding Buildspec.yml
A buildspec.yml
file acts as a blueprint for AWS CodeBuild, a service that automates build processes for various projects. It defines a series of phases and commands that CodeBuild executes to build, test, and package your application for deployment.
- Install: Used to install any dependencies required for building your application.
- Pre-build: Optional phase for executing tasks like cleaning build directories or generating configuration files.
- Build: The core phase where you build your application using specific commands.
- Post-build: Optional phase for performing tasks after the build is complete, such as uploading artifacts to an S3 bucket.
Step-by-Step Guide to Building the Buildspec.yml File
Install Dependencies:
version: 0.2
phases:
install:
commands:
- nohup /usr/local/bin/dockerd --host=unix:///var/run/docker.sock --host=tcp://127.0.0.1:2375 --storage-driver=overlay2 &
- timeout 15 sh -c "until docker info; do echo .; sleep 1; done"
Starts a detached Docker daemon (dockerd) to enable interaction with Docker commands within the build process.
Waits for the Docker daemon to become available before continuing.
Pre-build Steps:
...
pre_build:
commands:
- echo log in to Amazon ECR...
- aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username $ECR_LOGIN_USER --password-stdin $ECR_LOGIN_PASS
- REPOSITORY_URI=$REPO_URL
- IMAGE_TAG=${COMMIT_HASH:=latest}
- Retrieves login credentials from environment variables and logs them
- Assigns environment variables for the repository URI and image tag.
Build the Docker Image:
...
build:
commands:
- echo Build started on `date`
- echo Building the Docker image.
- echo log in to Amazon ECR...
- aws --version
- docker build -t $REPO_NAME .
- docker tag $REPO_NAME:latest $REPOSITORY_URI:latest
- Builds the Docker image using the current directory as the context.
- Tags the built image with the repository URI and the provided tag (latest by default).
Dockerfile for Docker Image:
For detailed guidance on crafting a multi-stage Dockerfile specifically for NestJS deployments, refer to this comprehensive article: Multi-stage Dockerfile for NestJS
This article provides a well-structured approach to building a Dockerfile. It optimizes image size and ensures efficient deployment of your NestJS application to AWS ECS.
Pushing the Docker Image to a Registry:
...
post_build:
commands:
- echo Build completed on `date`
- docker push $REPOSITORY_URI:latest
- printf '[{"name":"main-service","imageUri":"%s"}]' $REPOSITORY_URI:latest > imagedefinitions.json
- Pushes the built image to the ECR repository.
- Creates a JSON file (
imagedefinitions.json
) containing the pushed image information.
Conclusion
The final file is here.
version: 0.2
phases:
install:
commands:
- nohup /usr/local/bin/dockerd --host=unix:///var/run/docker.sock --host=tcp://127.0.0.1:2375 --storage-driver=overlay2 &
- timeout 15 sh -c "until docker info; do echo .; sleep 1; done"
pre_build:
commands:
- echo log in to Amazon ECR...
- aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username $ECR_LOGIN_USER --password-stdin $ECR_LOGIN_PASS
- REPOSITORY_URI=$REPO_URL
- IMAGE_TAG=${COMMIT_HASH:=latest}
build:
commands:
- echo Build started on `date`
- echo Building the Docker image.
- echo log in to Amazon ECR...
- aws --version
- docker build -t $REPO_NAME .
- docker tag $REPO_NAME:latest $REPOSITORY_URI:latest
post_build:
commands:
- echo Build completed on `date`
- docker push $REPOSITORY_URI:latest
- printf '[{"name":"main-service","imageUri":"%s"}]' $REPOSITORY_URI:latest > imagedefinitions.json
artifacts:
files: imagedefinitions.json
cache:
paths:
- '/root/.docker/cli-plugins'
- '/root/.npm/**/*'
- 'dist/**/*'
Caches various directories:
- Docker CLI plugins
- npm packages
- Application build output (dist directory)
By following this guide and tailoring the provided examples to your specific needs, you’ll have a buildspec.yml
file that automates the build and deployment process for your NestJS application to AWS ECS. This approach streamlines your development workflow. It ensures consistency. Additionally, it enables you to leverage the scalability and cost-effectiveness of AWS ECS for your NestJS deployments.
Additional Tips for deployment with AWS ECS:
- Security: Remember to implement best practices like using secrets managers for sensitive information and keeping your build processes secure.
- Version Control: Always store your
buildspec.yml
file in your version control system for tracking changes and collaboration. - Monitoring and Logging: Set up proper monitoring and logging for your deployed application to identify and troubleshoot any issues.
- Continuous Integration and Delivery: Integrate your
buildspec.yml
file into a CI/CD pipeline to automate the build, test, and deployment process upon code changes.
Follow these steps and best practices. You can create a reliable and efficient deployment process for your NestJS applications using AWS ECS and buildspec.yml
.
Subscribe
Enter your email below to receive updates.