DEV Community

Cover image for DEPLOYING "HNG_BOILERPLATE" EXPRESSJS APPLICATION (BACKEND) TO PROD SERVER
bankolejohn
bankolejohn

Posted on

DEPLOYING "HNG_BOILERPLATE" EXPRESSJS APPLICATION (BACKEND) TO PROD SERVER

Overview

This documentation details the deployment process of the backend of an Express.js boilerplate application to a production environment on an EC2 Ubuntu server using a GitHub Actions workflow. The deployment process includes setting up necessary dependencies, pulling the latest code, running tests, building the backend, and ensuring it runs as a service.

Prerequisites

  • EC2 Ubuntu Server: Running Ubuntu, with SSH access.
  • Node.js 20 installed on the server.
  • npm installed on the server.
  • Nginx installed and configured as a reverse proxy.
  • GitHub Repository: Hosting the Express.js boilerplate code.
  • GitHub Actions Runner: Installed and configured on the server to execute the deployment workflow.
  • Certbot for SSL certificate management.

Dependencies

  • Node.js 20
  • npm
  • Nginx
  • Yarn (for managing Node.js dependencies)
  • GitHub Actions Runner (self-hosted runner)

Deployment Workflow

name: Deploy to production

on:
  push:
    branches:
      - prod

jobs:
  deploy:
    runs-on: bp_runner
    defaults:
      run:
        working-directory: /var/www/aihomework/boilerplate/prod

    steps:
      - name: Checkout code
        uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '20' 

      - name: Remove old actions remote URL
        continue-on-error: true
        run: |
            git remote rm action

      - name: Stash or remove local changes
        run: |
            if git diff --quiet; then
              echo "No local changes to stash."
            else
              echo "Stashing local changes..."
              git stash --include-untracked || echo "Failed to stash changes. Attempting to reset..."
              git reset --hard || exit 1
            fi

      - name: Pull from GitHub
        id: pull
        run: |
            remote_repo="https://${GITHUB_ACTOR}:${{ secrets.GITHUB_TOKEN }}@github.com/${GITHUB_REPOSITORY}.git"
            git remote add action $remote_repo
            git pull $remote_repo prod

      - name: Install dependencies
        run: yarn install --frozen-lockfile

      - name: Run tests
        run: yarn test

      - name: Build the application
        run: yarn build && sudo rm -rf build

      - name: Setup and restart service
        run: |
          sudo cp server-script/aihomeworkprod.service /etc/systemd/system
          sudo systemctl daemon-reload
          sudo systemctl restart aihomeworkprod.service

      - name: Verify deployment
        run: |
          echo "Waiting for service to start..."
          sleep 10
          if sudo systemctl is-active --quiet aihomeworkprod.service; then
            echo "Deployment successful!"
          else
            echo "Deployment failed!"
            exit 1
          fi
Enter fullscreen mode Exit fullscreen mode
1. Triggering the Workflow
  • The workflow is triggered by a push to the prod branch.
2. Checking Out the Code
  • The actions/checkout@v3 action pulls the latest code from the prod branch, ensuring the full history is retrieved (fetch-depth: 0).
3. Setting Up Node.js
  • The workflow installs Node.js version 20 using the actions/setup-node@v3 action.
4. Managing Git Remotes and Local Changes
  • Remove Old Remote URL: Deletes any existing remote URL to prevent conflicts.
  • Stash or Remove Local Changes: Uncommitted changes are stashed or reset to maintain a clean working directory.
5. Pulling Latest Changes
  • The latest changes are pulled from the prod branch using the GitHub token for authentication.
6. Installing Dependencies
  • Node.js dependencies are installed using yarn install --frozen-lockfile to ensure consistency with the yarn.lock file.
7. Running Tests
  • Tests are executed using yarn test to verify the stability of the backend before deployment.
8. Building the Backend
  • The backend is built using yarn build, and previous build artifacts are removed to prevent conflicts.
9. Setting Up and Restarting the Service
  • The service file (aihomeworkprod.service) is copied to the /etc/systemd/system directory, and the systemd manager configuration is reloaded. The service is restarted to apply the latest changes.
10. Verifying Deployment
  • The workflow waits for the service to start and checks its status. If the service is active, the deployment is successful; otherwise, it fails.

Service Configuration (aihomeworkprod.service)

The service file defines how the backend of the Express.js application runs on the server. Below is a sample service configuration:

[Unit]
Description=Express.js Backend Application - Production
After=network.target

[Service]
ExecStart=/usr/bin/node /var/www/aihomework/boilerplate/prod/build/index.js
WorkingDirectory=/var/www/aihomework/boilerplate/prod
Restart=always
User=www-data
Group=www-data
Environment=NODE_ENV=production
Environment=PORT=3000

[Install]
WantedBy=multi-user.target
Enter fullscreen mode Exit fullscreen mode

Nginx Configuration

Nginx is used as a reverse proxy to route incoming traffic to the Express.js backend application. The following Nginx configuration includes the SSL setup using Certbot:

server {
    listen 80;
    server_name your-domain.com;

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
Enter fullscreen mode Exit fullscreen mode
SSL Certificate Setup

To obtain SSL certificates and configure Nginx with HTTPS, you can use the following command with Certbot:

sudo certbot --nginx -d your-domain.com
Enter fullscreen mode Exit fullscreen mode

This command will automatically configure Nginx with SSL, obtaining certificates from Let’s Encrypt.

Final Steps

  • Ensure Nginx is configured to point to the backend’s port.
  • Enable and start the systemd service: sudo systemctl enable aihomeworkprod.service and sudo systemctl start aihomeworkprod.service.
  • Monitor the service using sudo systemctl status aihomeworkprod.service.

NOTE

  • Ensure that you update the .env file with the required variables in order to ensure the application runs successfully.

Conclusion

This documentation outlines the automated deployment process for the backend of the Express.js boilerplate application, ensuring that the latest changes are consistently deployed to the production environment. By following the above steps, the backend can be reliably updated and maintained on the EC2 Ubuntu server with SSL-secured access.

Top comments (0)