Automatically Deploy Hugo Blog to Remote Server Using GitHub Actions

Once all the content of the Hugo blog is ready, it can be deployed to a remote server. This article explains how to automate the deployment of a Hugo blog to a remote server using GitHub Actions.

For security reasons, it is not recommended to log in to the remote server using a password. Instead, you can use SSH keys to log in. Create a new user on the remote server, generate SSH keys for that user, and configure GitHub Actions to use those keys to log in to the remote server and deploy the Hugo blog.

Generate SSH Key Pair Locally

The SSH key pair generated locally is used for the new user to log in to the remote server. To generate an SSH key pair locally:

1
ssh-keygen -t rsa -b 4096 -C "blog@zair.top"

Follow the prompts to set the file save path (set to ~/.ssh/github-blog-deploy) and passphrase (can be empty).

The generated files include:

  • Public key file: github-blog-deploy.pub
  • Private key file: github-blog-deploy

Configure SSH Public Key for New User on Remote Server

  1. Log in to the remote server:

    1
    
    ssh root@SSH_IP -p SSH_PORT 
  2. Create a new user:

    1
    
    sudo adduser deployuser
  3. Configure SSH login for the new user:

    1
    2
    3
    4
    5
    
    sudo mkdir /home/deployuser/.ssh
    sudo chmod 700 /home/deployuser/.ssh
    sudo touch /home/deployuser/.ssh/authorized_keys
    sudo chmod 600 /home/deployuser/.ssh/authorized_keys
    sudo chown -R deployuser:deployuser /home/deployuser/.ssh
  4. Copy the locally generated public key to the remote server:

    Add the contents of the github-blog-deploy.pub file to the /home/deployuser/.ssh/authorized_keys file:

    1
    
    cat ~/.ssh/github-blog-deploy.pub | ssh root@SSH_IP -p SSH_PORT  'cat >> /home/deployuser/.ssh/authorized_keys'

    Or manually copy the public key content and paste it into the authorized_keys file:

    1
    
    sudo nano /home/deployuser/.ssh/authorized_keys

    Paste the content of the github-blog-deploy.pub file and save.

  5. Set directory permissions for the new user: Create the website deployment directory and set permissions:

    1
    
    sudo chown -R deployuser:deployuser /var/www/public

Update GitHub Actions Configuration File

  1. Add the private key to GitHub Secrets:

    • Log in to GitHub and go to the repository where the Hugo blog is located.
    • Click Settings -> Secrets and variables -> Actions -> New repository secret.
    • Add a new Secret, SSH_PRIVATE_KEY, with the value being the content of the github-blog-deploy file (private key). Add the three Secrets SSH_PRIVATE_KEY, SSH_IP, and SSH_PORT according to the actual situation.
  2. Update the GitHub Actions configuration file:

Add the following file content:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
name: Deploy Hugo Site

on:
  push:
    branches:
      - main

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v2
        with:
          submodules: true  # This ensures submodules are cloned

      - name: Set up Hugo
        uses: peaceiris/actions-hugo@v2
        with:
          hugo-version: 'latest'
          extended: true  # Ensure the extended version is used

      - name: Build Hugo site
        run: hugo --minify

      - name: Deploy to remote server
        env:
          SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
          SSH_IP: ${{ secrets.SSH_IP }}
          SSH_PORT: ${{ secrets.SSH_PORT }}
        run: |
          set -x  # Enable debugging
          mkdir -p ~/.ssh
          echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
          chmod 600 ~/.ssh/id_rsa
          # Add debugging information to help diagnose ssh-keyscan issues
          ssh-keyscan -p $SSH_PORT $SSH_IP || true  # Continue even if ssh-keyscan fails
          ssh-keyscan -p $SSH_PORT $SSH_IP >> ~/.ssh/known_hosts
          ssh -o StrictHostKeyChecking=no -p $SSH_PORT deployuser@$SSH_IP "mkdir -p /var/www/public"
          rsync -avz -e "ssh -p $SSH_PORT" ./public/ deployuser@$SSH_IP:/var/www/public          
Buy me a coffee~
Tim AlipayAlipay
Tim PayPalPayPal
Tim WeChat PayWeChat Pay
0%