Setting Up Continuous Deployment for Node.js Applicaitons on Ubuntu
In this blog post, we will explore how to set up Continuous Deployment (CD) for a Node.js application using GitHub Actions.
Prerequisites
- A basic understanding of Git, GitHub, and Linux commands.
- A GitHub account and a repository.
- An Ubuntu server instance.
Understanding SSH Key.
Before diving into this blog, it's important to have a basic understanding of SSH keys and how they are used. If you're new to this concept, I highly recommend referring to this detailed blog post SSH Keys: A Beginner's Guide (zysk.tech) for a thorough understanding. Even if you're familiar with SSH keys, a quick refresher can be immensely helpful. So, take a moment to read up on SSH keys - it'll make the rest of this guide much clearer and more beneficial.
Adding Public key to GitHub
To clone your repository and pull code without needing to enter a password, you can add your public SSH key to GitHub. First, copy your public key using the following command:
cat ~/.ssh/id_ed25519.pub
Then, click this link to navigate to the SSH and GPG keys page on GitHub. Once logged in, click New SSH Key
give your key a title in the provided field, paste your copied public key into the Key
field, and then click Add SSH Key
. This will allow you to authenticate to GitHub securely without a password.
Adding Public Key to the authorized_keys File
As we have understood above, to enable SSH connections to this server, you must add your public key to the authorized_keys
file.
Begin by navigating to the .ssh
folder with the command:
cd ~/.ssh
Next, open or create the authorized_keys
file using:
sudo nano authorized_keys
Note: this command will also create the file if it does not already exist.
Paste your public key into this file to allow access.
Creating GitHub Workflow
With the basic setup complete, we’re ready to begin implementing Continuous Deployment. Start by opening your application’s root directory. Here, you’ll need to create a specific directory structure for GitHub Actions:
- Create a new folder named
.github
, if it doesn't already exist. - Inside the
.github
folder, create another folder namedworkflows
. - Within the
workflows
folder, create a file and name itdeploy.yml
(you can choose a different name if you prefer, but ensure it ends with.yml
).
This deploy.yml
file will contain the YAML script for your deployment workflow, defining the actions that GitHub will perform automatically every time you push changes to your repository.
here is a script for deploying a Monolithic Nestjs applicaiton
name: Integration Build & Deploy
on:
push:
branches: [BRANCH-NAME] # Replace BRANCH-NAME with the name of your branch
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy NodeJS app
uses: appleboy/ssh-action@v0.1.2
with:
host: ${{secrets.SSH_HOST}}
key: ${{secrets.SSH_KEY}}
username: ${{secrets.SSH_USERNAME}}
script: |
cd <APPLICATION_FOLDER_NAME> # Replace with the name of your application's directory
git checkout BRANCH-NAME # Ensure this matches the branch name above
git pull origin BRANCH-NAME # Ensure this matches the branch name above
echo 'Code is successfully pulled from the repository!'
if [ ${{secrets.UPDATE_NODE_MODULES}} == 'true' ]; then
echo 'Updating node modules...'
npm install
echo 'Node modules are successfully updated!'
fi
pm2 stop 0 # Replace 0 with your pm2 instance id
echo 'All running processes are successfully stopped!'
npm run build
echo 'Build is successfully completed!'
pm2 restart 0 # Replace 0 with your pm2 instance id
echo 'All processes are successfully restarted!'
Explanation of the Script:
- Trigger: This workflow is triggered on pushes to the specified branch.
- Job Setup: The job runs on the latest Ubuntu virtual environment provided by GitHub.
- Deployment Steps: The steps use
appleboy/ssh-action@v0.1.2
for SSH access. It allows the workflow to SSH into your server using credentials defined in GitHub secrets (SSH_HOST
,SSH_KEY
,SSH_USERNAME
). - Script Execution:
- The script navigates to your application’s directory, updates it from the specified branch.
- It conditionally updates Node modules if a secret (
UPDATE_NODE_MODULES
) is set to 'true'. - Uses
pm2
to stop and restart the application processes, ensuring zero downtime. - Completes by building and restarting the application.
This setup ensures that your application is automatically pulled, built, and restarted on your server whenever changes are made to the branch you specify.
Note: Adjust the placeholders and secrets according to your actual setup.
Note: In this setup pm2 will not work if you have installed node using nvm please make sure that you have installed node directly
Adding New Repository Secrets to GitHub
- Go to your GitHub repository where you want to add secrets.
- Select
Settings
option on the top bar - In the left sidebar of your repository’s settings page, click on
Secrets and variables
. This will expand a dropdown menu. - From the dropdown menu, select
Actions
under the Repository secrets section. - Click
New repository secret
to create a new secret, enter a name for your secret in theName
field, Paste the value of the secret into theSecret
field. ClickAdd secret
to save your new repository secret.
Secrets for the Workflow
Now we understood how to add secrets to the GitHub let's start adding secrets to our workflow.
SSH_HOST
add the public IP of the instance.SSH_USERNAME
username of the instance. you can find it out with the following commandwhoami
SSH_KEY
private key of the instance.UPDATE_NODE_MODULES
settrue
when you wanted to run thenpm i
command.
Once you have configured your GitHub Actions workflow and added all necessary secrets, pushing code to the specified branch in your repository will automatically trigger the workflow. Here’s how you can monitor the deployment process:
- Push Your Code: Commit your changes and push them to the branch that is monitored by your GitHub Actions workflow. This action will initiate the deployment process defined in your
.yml
file. - Check the Workflow Status:
- To see the status of the deployment, go to your GitHub repository and click on the
Actions
tab. This tab is located at the top of your repository page. - Inside the Actions tab, you will find a list of all the workflow runs. Click on a specific run to view detailed information, including each step’s success or failure, logs, and the duration of the process.
By following these steps, you can ensure that your Node.js application is continuously deployed smoothly and keep track of each deployment’s progress directly within GitHub.