GitHub Actions CI/CD Pipeline to a VPS: Complete 2026 Guide

Published on

Automate deployment so every git push to main triggers a test run and auto-deployment to your VPS. Here's a complete working pipeline setup.

Written by Alex van der Berg – Infrastructure Engineer at Space-Node – 15+ years combined experience in game server hosting, VPS infrastructure, and 24/7 streaming solutions. Read author bio →

GitHub Actions CI/CD Pipeline to a VPS: Complete 2026 Guide

Manual deployment — SSH into server, git pull, restart application — doesn't scale and is error-prone. GitHub Actions automates this: push code, tests run, deployment happens automatically if tests pass.

The Basic Pipeline

# .github/workflows/deploy.yml
name: Test and Deploy

on:
  push:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - run: npm ci
      - run: npm test

  deploy:
    needs: test        # Only runs if test job passes
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Deploy to VPS
        uses: appleboy/ssh-action@v1.0.3
        with:
          host: ${{ secrets.VPS_IP }}
          username: ${{ secrets.VPS_USER }}
          key: ${{ secrets.VPS_SSH_KEY }}
          script: |
            cd /var/www/my-app
            git pull origin main
            npm ci --production
            pm2 reload my-app

Setting Up SSH Key Authentication for CI/CD

# Generate a dedicated deploy key (on your local machine):
ssh-keygen -t ed25519 -C "github-actions-deploy" -f ~/.ssh/deploy_key

# Add public key to your VPS:
ssh-copy-id -i ~/.ssh/deploy_key.pub user@your-vps-ip

# Add PRIVATE key to GitHub Secrets:
# Repository → Settings → Secrets and variables → Actions → New repository secret
# Name: VPS_SSH_KEY
# Value: contents of ~/.ssh/deploy_key (private key)

Docker Compose Deployment Pattern

For containerised applications:

      - name: Deploy Docker Stack
        uses: appleboy/ssh-action@v1.0.3
        with:
          host: ${{ secrets.VPS_IP }}
          username: ${{ secrets.VPS_USER }}
          key: ${{ secrets.VPS_SSH_KEY }}
          script: |
            cd /opt/my-app
            git pull origin main
            docker compose pull
            docker compose up -d --remove-orphans
            docker image prune -f

Zero-Downtime for Node.js with PM2

# On your VPS app directory:
# pm2 reload performs graceful restart (processes existing requests before shutdown)
pm2 reload ecosystem.config.js --update-env

Use pm2 reload (not pm2 restart) for zero-downtime deployments — it gracefully cycles processes rather than killing them.

Notifications on Deployment

Add a Slack or Discord notification on deployment completion:

      - name: Notify Discord
        if: always()
        run: |
          curl -X POST \
            -H "Content-Type: application/json" \
            -d "{"content": "Deploy ${{ job.status }}: ${{ github.event.head_commit.message }}"}" \
            ${{ secrets.DISCORD_WEBHOOK }}

Deploy your applications automatically to Space-Node VPS

About the Author

Alex van der Berg – Infrastructure Engineer at Space-Node – Experts in game server hosting, VPS infrastructure, and 24/7 streaming solutions with 15+ years combined experience.

Since 2023
500+ servers hosted
4.8/5 avg rating

Our team specializes in Minecraft, FiveM, Rust, and 24/7 streaming infrastructure, operating enterprise-grade AMD Ryzen 9 hardware in Netherlands datacenters. We maintain GDPR compliance and ISO 27001-aligned security standards.

View Space-Node's full team bio and credentials →

Launch Your VPS Today

Get started with professional VPS hosting powered by enterprise hardware. Instant deployment and 24/7 support included.

GitHub Actions CI/CD Pipeline to a VPS: Complete 2026 Guide