Skip to content

Instantly share code, notes, and snippets.

@muhammedfurkan
Forked from zihadmahiuddin/AUTO_DEPLOY.md
Created November 3, 2022 07:26
Show Gist options
  • Save muhammedfurkan/70d02251b67b605aae4b8bddfc192845 to your computer and use it in GitHub Desktop.
Save muhammedfurkan/70d02251b67b605aae4b8bddfc192845 to your computer and use it in GitHub Desktop.
GitHub Auto Deploy for NodeJS apps using Webhooks

Introduction

Table of Contents

What is this?

GitHub Auto Deploy for NodeJS apps using Webhooks

This is a small tutorial on setting up auto deployment of NodeJS apps so that your app is deployed automatically on your VPS when you push. This tutorial will use webhook.

Why?

Logging in to your VPS, pulling the changes and restarting your app every time you change something can sometimes be annoying. This method will help you automate that process. All you need to do is just push.

What are we using?

In this tutorial, I will use NodeJS v12 on a fresh Ubuntu 20.04 VPS and a very simple "Hello World" express app. But most of the things should work for you.

Setting Up

The Service

First of all, we will convert our node app to a "service". Our service will be very basic but you can add more stuff to it if you need them. This is what we will have for our use case:

[Unit]
Description=Express Hello World

[Service]
Type=simple
WorkingDirectory=/home/user/express-helloworld
ExecStart=/usr/bin/yarn start
Restart=always

What's going on here?

First of all, in the Unit group, we specify what our service is. You can put whatever you want in here.

Then in the Service group, we define the service type as simple. (Should be fine in most cases)

And then we specify our WorkingDirectory. This is where the commmands will be executed from. Most of the time, it's your project's root folder.

Then we have ExecStart that defines which command will be executed when this service starts. As I have a start script added in my package.json file, I simply set it to run yarn start. And I set it to take yarn from /usr/bin/yarn. If you want to use node directly and your main script is called app.js, then you can set ExecStart to /usr/bin/node app.js and it should work fine.

Finally, setting the Restart option to always tells the system to restart this service if it crashes. You can read more about this option here

What to do with this?

If you've never written a service file before, you might be confused and/or wondering what you should do with the above. The above text is a "service file" that defines the properties of a service. What you need to do is create a file in the /etc/systemd/system folder of your VPS and put the content in there. You can call it whatever but the extension needs to be .service. I will call mine express-hello-world.service. So the file path is /etc/systemd/system/express-hello-world.service.

After you're done with that, you need to execute the following command to make your service available:

sudo systemctl daemon-reload

Now to verify that your service has been created and is working properly, you can try the following command:

sudo service express-hello-world start  # to start the service
sudo service express-hello-world status # to check the status of the service

If it says running then it's all good.

SSH Authentication

Generating an SSH key

If you already have an SSH key, you can skip this step. To generate a SSH key, you can use the ssh-keygen command. It is going to ask you some questions. I usually accept the default values, they are fine in most cases as far as I know.

This will generate a new SSH key and save it inside the .ssh folder of your user folder.

Then you will need to get the public key and add it to your GitHub account. To get the public key, you can use the following commmand:

cat ~/.ssh/id_rsa.pub

This command will print your SSH public key. Go ahead and follow the next step to add this key to your GitHub account.

Adding the SSH key to your GitHub Account

If you already use SSH with GitHub, you can skip this step. Otherwise you can follow this guide to set it up.

Webhook

We're almost there! Just a few more steps.

Installing webhook

Installing webhook on Ubuntu is really easy. All you need to do is

sudo apt install webhook

Setting up the "updater" script

Next, we need to write a script that webhook will run when something is pushed to our GitHub Repository.

A basic script would look like this:

#!/bin/bash
cd /home/user/express-helloworld    # we go inside our project folder
git pull                            # we pull the latest changes
yarn                                # we install the dependencies
service express-hello-world restart # we restart our app's service
# if you need to run some more comands before restarting your app, you can put them
# before the restart command

Make sure you make the script executable by running chmod +x script.sh.

I usually put this script in my /home/user folder and call it update-PROJECT.sh. So in this case, I'll call it update-express-hello-world.sh so the full path is /home/user/update-express-hello-world.

Configuring webhook

Then we need to configure webhook. We need to give a config file to webhook. that defines what it will do when a request is sent on a specific path.

Below is a simple webhook config:

[
  {
    "id": "update-express-hello-world",
    "execute-command": "/home/user/update-express-hello-world.sh",
    "command-working-directory": "/home/user/"
  }
]

Now, assuming webhook is running on port 9000 and your VPS has the IP Address 101.22.33.44, if a HTTP request is sent to http://101.22.33.44:9000/hooks/update-express-hello-world, webhook will go to the command-working-directory of the update-express-hello-world hook, which is /home/user/ and then run the /home/user/update-express-hello-world.sh script which will pull the changes, install the dependencies and restart our app.

Save the webhook config file as /etc/webhook.conf and then restart webhook with the following command:

sudo service webhook restart

Again, you can check the status of the webhook service as mentioned at the bottom of this section

The GitHub Repository

Finally, we reached the last step, whew!

What we need to do in this step is very simply visiting our repository on GitHub and go to the Settings tab. Then we need to click the Webhooks section which you can find on the left.

After that, we need to click on the Add webhook button. GitHub might ask for your password at this step, enter the password to proceed.

The Payload URL is basically http://VPS_IP:WEBHOOK_PORT/hooks/HOOK_ID where VPS_IP is the IP address/domain name of your VPS, WEBHOOK_PORT is the port webhook is running on (9000 by default) and HOOK_ID is the id of your hook that you set in the webhook config file in this step

You can leave the other fields as they are and click on Add webhook.

Now you can test the webhook. Simply commit and push to your repository and it should be updated on your VPS.

If you have any questions, feel free to comment here, I'll try my best to reply. Thanks and happy coding!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment