How to setup continuous delivery

Learn how to setup CD of a website on a VPS using Github Actions

Zhehai Zhang |  

Sun Nov 07 2021 |  

2 min read

Setup

Make sure to have

  • GitHub account
  • Github repo
  • VPS

What will we get at the end?

Our end goal is to be able to push to a repository, and then on the VPS side:

  1. Pull from the repository
  2. Run the installation requirements
  3. Reload things that are serving it (pm2 in my case)
  4. Step back and relax as your website auto deploys!

Configuring the GitHub repository

In order to run actions on the vps, GitHub needs access. Hence, we'll create an ssh key for it.

cd ~/.ssh
ssh-keygen -t rsa -b 4096 -C "[email protected]"
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys

Copy the private key by displaying it:

cat ~/.ssh/id_rsa

Now head over to your GitHub repository, under Settings -> Secrets -> New repository secret we will create 4 secrets:

HOST: hostname/ip address of vps
USERNAME: username to ssh into vps
SSHKEY: the private key you copied earlier
PORT: 22

Configuring the GitHub Action

Under your repo, create a .github/workflows folder and create a deploy.yaml with the contents below:

name: Deploy Frontend
on:
  push:
    branches: [master]
jobs:
  deploy-frontend-job:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2

      - name: Pull from GitHub repo
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.HOST }}
          USERNAME: ${{ secrets.USERNAME }}
          PORT: ${{ secrets.PORT }}
          KEY: ${{ secrets.SSHKEY }}
          script: |
            cd /var/www/personalwebsite
            git pull
            npm install
            npm run build
            pm2 reload 0

We only want pushes that go to the master branch, and this runs the deploy-frontend-job job. Note that you can do whatever branch you want. We are calling a ssh-action, which runs the script in the vps once we have logged on.

I am going to the directory, pulling from GitHub, installing packages, and then reloading pm2, which I'm using to serve.