How to deploy Node.js App to a VPS using GitHub Actions?

How to deploy Node.js App to a VPS using GitHub Actions?

Introduction to CI/CD

In modern software development, Continuous Integration and Continuous Deployment (CI/CD) are essential practices that automate the process of integrating new code, testing it, and deploying it to production. CI/CD pipelines help developers maintain a smooth, consistent workflow, eliminating repetitive manual tasks. With GitHub Actions, we can automate the deployment of a Node.js application to a Virtual Private Server (VPS) whenever changes are pushed to the repository.

In this guide, we will walk through the process of using GitHub Actions to automatically deploy a Node.js app to a VPS.


Prerequisites

Before proceeding with the setup, ensure you have the following in place:

  1. A GitHub Repository
    • A GitHub repository hosting your Node.js application.
  2. A VPS with SSH Access
    • A VPS with SSH access (such as from DigitalOcean, AWS EC2, or similar providers). Make sure you have root or sudo access.
  3. A Domain or Static IP Address
    • The public IP address or domain name pointing to your VPS.
  4. Node.js Installed on the VPS
  5. Git Installed
    • Git should be installed on your local machine.
  6. SSH Keys (Optional but Recommended)
    • SSH keys allow secure passwordless access to your VPS. If not set up, this tutorial will guide you through generating and configuring SSH keys.
  7. A Basic Node.js Application
    • A Node.js app with scripts for npm run build or similar. If using a different stack, adjust the build steps accordingly.
  8. GitHub Actions Permissions
    • GitHub Actions must be enabled for your repository. Check this under Settings > Actions in your repository.
  9. Familiarity with YAML Syntax
    • Since GitHub Actions workflows are written in YAML, some familiarity with the syntax will help you customize the workflow


Step 1: Logging into the VPS

Before setting up automatic deployment, you need to establish a connection to your server. The most common way to do this is via SSH (Secure Shell), which provides a secure channel for communication between your local machine and the server.

To log into your VPS using the terminal, run the following command:

ssh <your-username>@<your-server-ip-address>

Replace <your-username> with the username you use on the server and <your-server-ip-address> with the actual IP address of your VPS. If you have not set up SSH keys (which we’ll discuss in the next step), you'll be prompted to enter your password for the username. Once authenticated, you’ll have access to the server through the command line.


Step 2: Setting Up SSH Keys for Secure Access

SSH keys are used to establish a secure, passwordless connection between your local machine and the server. This is especially useful when setting up automated deployments, as it avoids the need to manually enter passwords every time a deployment happens.

Starting the SSH Agent

Before generating SSH keys, start the SSH agent on your local machine by running:

eval `ssh-agent -s`

This step is crucial because the SSH agent helps manage the SSH keys during the session. Missing this step is a common mistake and can result in failed key generation or improper access. After running this command, the terminal will return something like:

Agent pid 1685199

This indicates that the agent is running correctly.

Generating the SSH Key Pair

Now, generate the SSH key pair, which includes a private and public key:

ssh-keygen -t rsa -b 4096
  • -t rsa: Specifies the type of key (RSA is widely used and recommended).
  • -b 4096: Generates a key with a 4096-bit length for added security.

After running the command, follow the on-screen instructions. You can leave the file location as the default and skip entering a passphrase unless you want to add an extra layer of security. Once completed, you’ll have both a private key (stored in a file named id_rsa) and a public key (stored in a file named id_rsa.pub).


Step 3: Copying the Public Key to the Server

To allow your Github server to recognize and trust your server computer / VPS for passwordless access, you need to add your public key to the server’s authorized_keys file.

Run the following command to copy the content of your public key to the authorized_keys file on your VPS (server):

cat <path/to/public/key> >> ~/.ssh/authorized_keys

Replace <path/to/public/key> with the location of your public key. This file will usually be located at ~/.ssh/id_rsa.pub. Adding the public key to the authorized_keys file allows the server to authenticate your machine without needing a password each time.


Step 4: Copying the Private Key for GitHub Secrets

In order to set up automated deployments with GitHub Actions, GitHub needs access to the private SSH key so that it can log into your VPS and transfer files. First, you need to copy the private key from your local machine:

cat <path/to/private/key>

The private key is usually located in the ~/.ssh/id_rsa file on your local machine. Be sure to copy the entire key, including the lines:

-----BEGIN OPENSSH PRIVATE KEY-----
...
-----END OPENSSH PRIVATE KEY-----

This key will be added to your GitHub repository as a secret, allowing GitHub Actions to use it for authentication when deploying code.


Step 5: Storing Secrets in GitHub

GitHub Secrets allow you to securely store sensitive information such as SSH keys, tokens, and environment variables. Here’s how to store your SSH-related secrets:

  1. Log into your GitHub account and navigate to the repository where you want to set up automated deployment.
  2. Click on Settings in the repository menu.
  3. Scroll down to Secrets and Variables under Security and click Actions.
  4. Click New repository secret and add the following secrets:
    • SSH_PRIVATE_KEY: Paste the content of your private key file (copied in the previous step).
    • SSH_USER: The username you use to log into the server.
    • SSH_HOST: The IP address or hostname of your server.
    • SSH_DIR: The directory on the server where you want to deploy your application.
    • SSH_PORT : Usually 22

Double-check the values before saving because once secrets are stored, you won’t be able to view or edit them directly.


Step 6: Setting Up GitHub Actions Workflow

Now, let’s configure the GitHub Actions workflow that will automatically deploy the application to your VPS every time new code is pushed to the main branch.

  1. Navigate to the Actions tab of your GitHub repository.
  2. Click Set up a workflow yourself.
  3. Replace the existing code with the following workflow:
name: SSH Deployment

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest
    name: Build and Deploy

    steps:
      - uses: actions/checkout@master

      - name: Set up Node.js
        uses: actions/setup-node@v1
        with:
          node-version: 20
          
      - run: npm i
      - run: npm run build
      
      - name: Deploy to VPS
        uses: nogsantos/scp-deploy@master
        with:
          src: ./public/*
          host: ${{ secrets.SSH_HOST }}
          remote: ${{ secrets.SSH_DIR }}
          port: ${{ secrets.SSH_PORT }}
          user: ${{ secrets.SSH_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}

Let’s break this down:

  • The workflow is triggered when a push is made to the main branch.
  • The workflow checks out the code using actions/checkout.
  • It sets up a Node.js environment and installs dependencies (npm i).
  • The code is built with npm run build.
  • Finally, the nogsantos/scp-deploy action is used to copy the

built files to your VPS using the SSH keys and secrets you configured earlier.


Conclusion

Setting up CI/CD with GitHub Actions for VPS deployment offers a seamless and automated way to deploy your application. By following these steps, your deployment process becomes faster, more secure, and less error-prone. Every time you push changes to the main branch, your application will automatically be built and deployed to the VPS, reducing manual intervention and ensuring consistency in deployment.

This setup is perfect for small to medium-sized projects hosted on VPS servers, and it demonstrates the power of combining GitHub Actions with SSH for continuous deployment.


Visit my website and join with me as a business partner — Madusanka Premaratne — Entrepreneur | Founder & CEO at Knovik | Director of OECSL

Join 20,000+ Followers on Facebook — Madusanka Premaratne | Facebook

Join 4,500+ Followers on LinkedIn — Madusanka Premaratne — Venture Capitalist | LinkedIn

Join 2,000+ Followers on Instagram — Madusanka Premaratne (@madusankapremaratne)