
Streamlining Deployment with Github Actions
- Patrick Kenekayoro
- Git , Deployment
- December 23, 2024
Deploying my site used to be straightforward. I have a VPS on Linode that I set up using Ansible. The workflow was simple: push to GitHub, SSH into the Linode server, pull the code from GitHub, and run the npm run build
command.
This approach worked fine—until I started fixing typos frequently. The repetitive steps of pushing to GitHub, SSHing into the server, pulling updates, and running the build command quickly became tiresome.
I also realized that Hugo already provides a workflow to deploy directly to GitHub Pages when code is pushed to the main branch. So, I decided to automate the deployment process to my Linode VPS. Here’s how I refined it.
Version 1 - Build on VPS
The first step was to replicate my manual process: pull the code from GitHub and run the build command on the VPS. Here’s how the workflow looked:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Deploy to VPS
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SERVER_NAME }}
username: ${{ secrets.SSH_USERNAME }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd ${{ secrets.PROJECT_PATH }}
git pull origin main
npm ci
npm run build
This setup worked, but it felt like overkill for a simple Hugo site. It’s more suited for complex build processes. For my use case, building the site on GitHub and copying the generated files to the VPS seemed more efficient. By doing so, I could avoid having tools like Go or npm installed on the VPS altogether.
Version 2 - Build on GitHub and copy site to VPS
To simplify the deployment process, I moved the build step to GitHub and updated the workflow to copy the generated site files to the VPS. Here’s the complete workflow:
name: Deploy Site
on:
# Runs on pushes targeting the default branch
push:
branches: ["main"]
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
# Environment variables available to all jobs and steps in this workflow
env:
HUGO_ENV: production
HUGO_VERSION: "0.121.2"
GO_VERSION: "1.20.5"
NODE_VERSION: "20.0.0"
TINA_CLIENT_ID: ${{ vars.TINA_CLIENT_ID }}
TINA_TOKEN: ${{ vars.TINA_TOKEN }}
jobs:
# Build job
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: Install Hugo
run: |
curl -LO "https://github.com/gohugoio/hugo/releases/download/v${{ env.HUGO_VERSION }}/hugo_extended_${{ env.HUGO_VERSION }}_Linux-64bit.tar.gz"
tar -xvf hugo_extended_${{ env.HUGO_VERSION }}_Linux-64bit.tar.gz
sudo mv hugo /usr/local/bin/
rm hugo_extended_${{ env.HUGO_VERSION }}_Linux-64bit.tar.gz
hugo version
- name: Install Go
run: |
curl -LO "https://dl.google.com/go/go${{ env.GO_VERSION }}.linux-amd64.tar.gz"
sudo tar -C /usr/local -xzf go${{ env.GO_VERSION }}.linux-amd64.tar.gz
echo "export PATH=$PATH:/usr/local/go/bin" >> $GITHUB_ENV
rm go${{ env.GO_VERSION }}.linux-amd64.tar.gz
go version
- name: Setup Project
run: npm run project-setup
- name: Install npm dependencies
run: npm install
- name: Build site
run: npm run build
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./public
- name: Deploy to VPS
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SERVER_NAME }}
username: ${{ secrets.SSH_USERNAME }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
# Remove existing files in the public directory
rm -rf ${{ secrets.PROJECT_PATH_TEST }}/public/*
# Exit the script if any command fails
set -e
- name: Copy Built Files to VPS
uses: appleboy/scp-action@master
with:
host: ${{ secrets.SERVER_NAME }}
username: ${{ secrets.SSH_USERNAME }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
source: "./public/*"
target: "${{ secrets.PROJECT_PATH }}/public"
strip_components: 1
This workflow leverages GitHub Actions to handle the build process and deploys the final site files to the VPS, and it’s only a slight tweak from the Sample workflow provided in Hugo.
Setting Up SSH Keys
To enable GitHub to access your VPS, you’ll need to set up SSH keys:
Generate an SSH key pair
Run the following command on your local machine to create a new SSH key pair:
ssh-keygen -t rsa -b 4096 -C "github_deploy_key"
Add the public key to your server
Copy the contents of the
id_rsa.pub
file and append it to the~/ssh/authorized_keys
file on your server:cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
Add the private key to GitHub
In the GitHub Repository, add a new secret named
SSH_PRIVATE_KEY
and paste the contents of the generated private key
Happy coding! 🚀
Feel free to use this Markdown content for your blog or website. If you have any more requests or questions, let me know!