DEV Community

Integration Ninjas
Integration Ninjas

Posted on

Deploy Node.js Application to AWS EC2 using GitLab CI

Introduction

Automating deployments with GitLab CI/CD is a powerful way to streamline your development workflow. In this guide, we'll walk through the process of deploying a Node.js application to an AWS EC2 instance using GitLab CI/CD and Docker. This setup ensures that every new commit is automatically built, pushed to a container registry, and deployed to your server.

Prerequisites

  • Node.js application: Ensure you have a Node.js application ready for deployment.
  • GitLab repository: Create or use an existing repository to host your application code.(Example Repo)
  • Docker installed: Install Docker locally(if running self-hosted runner) to build and manage container images. If you're running workflow with GitHub hosted runners then Docker is already installed there.
  • AWS account: Sign up for a free AWS account if you haven't already.
  • EC2 instance: Create an EC2 instance in AWS with appropriate specifications for your application. Configure security groups to allow inbound traffic on the port your application uses (e.g., port 3000).
  • SSH Client: Install an SSH client like PuTTY or Terminal (on macOS/Linux) to connect to your EC2 instance.

AWS EC2 Setup

  1. Use below commands to setup Docker:

    sudo apt-get update
    sudo apt-get install docker.io -y
    sudo systemctl start docker
    sudo docker run hello-world
    docker ps
    sudo chmod 666 /var/run/docker.sock
    sudo systemctl enable docker
    docker --version
    
  2. Use below reference to setup self-hosted runner on EC2:

Install GitLab Runner manually on GNU/Linux | GitLab

GitLab product documentation.

favicon docs.gitlab.com
  1. Once you create runner, use this reference to register the GitLab runner on that EC2 machine.

Flow Chart

CI/CD Workflow

Now, follow below steps to create required Docker file and .gitlab-ci.yml file to deploy you Node.js code on AWS EC2:

Step 1: Dockerizing the Node.js Application

First, let's create a Dockerfile to containerize our application:
Within your application directory, create a file named Dockerfile with the following content, replacing <IMAGE_NAME> with your desired image name and <PORT> with your application's port:

FROM node:20-alpine3.18
WORKDIR /app
COPY package.json ./
RUN npm install
COPY . .
EXPOSE 5000
CMD ["npm","run","start"]
Enter fullscreen mode Exit fullscreen mode

This Dockerfile:

  • Uses Node.js 20 on Alpine Linux for a lightweight image
  • Sets the working directory to /app
  • Installs dependencies
  • Copies the application files
  • Exposes port 5000 (adjust if needed)
  • Runs the application using npm run start

Build and test your Docker image locally:

docker build -t nodejs-app .
docker run -p 5000:5000 nodejs-app
Enter fullscreen mode Exit fullscreen mode

If everything works, move to the next step!

Step 2: Setting Up GitLab CI/CD Pipeline

To automate deployment, create a .gitlab-ci.yml file in your project root:

default:
  image: docker:24.0.5
  services:
    - docker:24.0.5-dind
  before_script:
    - docker info

stages:
  - build
  - deploy

build_job:
  stage: build
  script: |
    echo "Building the application.."
    docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
    docker build -t integrationninjas/nodejs-app:$CI_COMMIT_SHA .
    docker push integrationninjas/nodejs-app:$CI_COMMIT_SHA

deploy_job:
  stage: deploy
  script: |
    docker pull integrationninjas/nodejs-app:$CI_COMMIT_SHA
    docker rm -f nodejs-app-container
    docker run -d -p 5000:5000 --name nodejs-app-container integrationninjas/nodejs-app:$CI_COMMIT_SHA
  tags:
    - ec2-runner
  only:
    - deploy-to-ec2
Enter fullscreen mode Exit fullscreen mode

Understanding the Pipeline

  1. Default Section:

    • Uses Docker-in-Docker (dind) to enable Docker builds inside the GitLab Runner.
  2. Stages Section:

    • Defines two stages – build and deploy.
  3. build_job:

    • Logs into Docker Hub.
    • Builds the Docker image with the commit SHA as the tag.
    • Pushes the image to Docker Hub.
  4. deploy_job:

    • Pulls the latest image from Docker Hub.
    • Removes the old container (if running).
    • Runs the new container on port 5000.
    • Uses the GitLab Runner tag ec2-runner to execute on an AWS EC2 instance.
    • Triggers only when pushed to the deploy-to-ec2 branch.

Now, when you push changes to the deploy-to-ec2 branch, GitLab CI/CD will automatically build and deploy your app! πŸš€

Step 4: Testing the Deployment

Once the pipeline completes, check if your app is running on EC2:

curl http://your-ec2-ip:5000
Enter fullscreen mode Exit fullscreen mode

You should see your application response! πŸŽ‰

Conclusion

With this setup, you've successfully automated the deployment of a Node.js application to AWS EC2 using GitLab CI/CD and Docker. Now, every commit to the deploy-to-ec2 branch will trigger an automatic build and deployment process. This approach ensures:

βœ… Faster and reliable deployments
βœ… Consistency across environments
βœ… Less manual effort, thanks to automation.

πŸ’¬ Questions? Drop them below! πŸš€

Heroku

Build apps, not infrastructure.

Dealing with servers, hardware, and infrastructure can take up your valuable time. Discover the benefits of Heroku, the PaaS of choice for developers since 2007.

Visit Site

Top comments (0)

Image of Docusign

πŸ› οΈ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more