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:
- A GitHub Repository
- A GitHub repository hosting your Node.js application.
- 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.
- A Domain or Static IP Address
- The public IP address or domain name pointing to your VPS.
- Node.js Installed on the VPS
- Ensure Node.js and npm are installed on both your local machine and VPS. You can follow the Node.js installation guide for setup.
- Git Installed
- Git should be installed on your local machine.
- 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.
- 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.
- A Node.js app with scripts for
- GitHub Actions Permissions
- GitHub Actions must be enabled for your repository. Check this under Settings > Actions in your repository.
- 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:
- Log into your GitHub account and navigate to the repository where you want to set up automated deployment.
- Click on Settings in the repository menu.
- Scroll down to Secrets and Variables under Security and click Actions.
- 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.
- Navigate to the Actions tab of your GitHub repository.
- Click Set up a workflow yourself.
- 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)