A More Stable GitHub Actions Deployment Solution: Replacing Jenkins and MCP
The author compares four cumbersome blog‑deployment methods—Jenkins, manual CLI, unstable MCP service, and direct SSH—and then details a reliable GitHub Actions workflow that builds the site, caches npm, and deploys it to an Ubuntu server via SSH and rsync.
I maintain a personal blog at passjava.cn where new articles are published. Previously I tried four approaches to push updates to the server, each with significant drawbacks:
Method 1: Use Jenkins to package and deploy – requires multiple steps.
Method 2: Upload via local command line – adds an extra manual step.
Method 3: Call the MCP service – unstable, sometimes succeeds and sometimes fails.
Method 4: Log into the remote server, pull the latest GitHub code and run build – depends on a Node environment and frequently fails to install npm packages.
Looking for a better solution, I turned to GitHub Actions.
How GitHub Actions Works
When code is pushed to GitHub, the Action detects the commit and starts a job defined in a workflow file.
Preparation on the Ubuntu Server
# Ensure the directory exists and is writable
sudo mkdir -p /nfs-data/passjava/passjava-learning
# Change ownership to the ubuntu user (no sudo needed later)
sudo chown -R ubuntu:ubuntu /nfs-data/passjava/passjava-learning
# Verify permissions
ls -la /nfs-data/passjava/Configure Password‑less SSH
Generate a deployment key pair (press Enter for all prompts):
$ ssh-keygen -t ed25519 -C "github-deploy" -f ~/.ssh/github-deployAdd the public key to authorized_keys on the server:
sudo sh -c 'cat ~/.ssh/github-deploy.pub >> ~/.ssh/authorized_keys'Copy the private key content for later use:
cat ~/.ssh/github-deployAdd Repository Secrets
In GitHub go to Settings → Secrets and variables → Actions and create three secrets: SERVER_IP – your server’s public IP. SSH_USER – set to ubuntu (fixed value). SSH_PRIVATE_KEY – the full private‑key text copied above.
Create the Workflow File
Place .github/workflows/deploy.yml in the project root with the following content:
name: Build and Deploy Docs
on:
push:
branches: [main] # trigger on pushes to main
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
# 1. Checkout code
- name: Checkout code
uses: actions/checkout@v4
# 2. Set up Node.js
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "22"
# 3. Cache npm dependencies
- name: Cache dependencies
uses: actions/cache@v3
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
# 4. Install dependencies
- name: Install dependencies
run: npm install
# 5. Build static site
- name: Build docs
run: npm run docs:build
# 6. Deploy to Ubuntu server via rsync
- uses: webfactory/[email protected]
with:
ssh-private-key: "${{ secrets.SSH_PRIVATE_KEY }}"
- name: Deploy to Ubuntu Server
uses: easingthemes/ssh-deploy@main
env:
SSH_PRIVATE_KEY: "${{ secrets.SSH_PRIVATE_KEY }}"
REMOTE_HOST: "${{ secrets.SERVER_IP }}"
REMOTE_USER: "${{ secrets.SSH_USER }}"
SOURCE: "dist/"
TARGET: "/nfs-data/passjava/passjava-learning/dist"
ARGS: "-avz --delete"Rsync Options Explained
--delete: Remove files on the target that no longer exist locally, achieving a full mirror.
Omit --delete if you want to keep extra files on the server.
The ssh-deploy action runs rsync with the specified arguments, allowing you to choose between different synchronization strategies (add‑only, full mirror, add‑without‑overwrite, update‑only, etc.).
Result
After committing the workflow, GitHub Actions executes the steps, builds the documentation, and synchronizes the dist/ directory to the remote server. The site becomes available at www.passjava.cn.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Wukong Talks Architecture
Explaining distributed systems and architecture through stories. Author of the "JVM Performance Tuning in Practice" column, open-source author of "Spring Cloud in Practice PassJava", and independently developed a PMP practice quiz mini-program.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
