Deploying code from GitHub to your GoZen VPS is one of the most common developer workflows. This guide covers three approaches, from simplest to most automated.

Method 1: Manual Git Pull (Simplest)

The most straightforward approach. SSH into your server, clone the repo, and pull updates when needed.

Initial Setup

  1. SSH into your server:

      ssh root@your-server-ip
      
  2. Generate an SSH key on the server (if you don’t have one):

      ssh-keygen -t ed25519 -C "server@yourdomain.com"
    cat ~/.ssh/id_ed25519.pub
      
  3. Add the public key to GitHub:

    • Go to your repo > Settings > Deploy keys > Add deploy key
    • Paste the public key
    • Check “Allow write access” only if the server needs to push
  4. Clone the repository:

      cd /var/www
    git clone git@github.com:yourusername/yourrepo.git yourdomain.com
      

Deploying Updates

Whenever you push changes to GitHub:

  ssh root@your-server-ip
cd /var/www/yourdomain.com
git pull origin main
  

If your project needs a build step:

  git pull origin main
npm install          # or composer install, pip install, etc.
npm run build        # if applicable
sudo systemctl restart nginx   # or your web server
  

Method 2: Webhook + Deploy Script

Automate the pull by having GitHub notify your server whenever you push.

1. Create a Deploy Script

On your server, create a script that pulls and builds:

  sudo nano /var/www/deploy.sh
  
  #!/bin/bash
cd /var/www/yourdomain.com
git pull origin main 2>&1

# Add build steps if needed
# npm install
# npm run build

# Restart services if needed
# sudo systemctl restart nginx

echo "Deployed at $(date)"
  
  chmod +x /var/www/deploy.sh
  

2. Set Up a Webhook Listener

Install a lightweight webhook server:

  sudo apt install webhook
  

Create a webhook config:

  sudo nano /etc/webhook.conf
  
  [
  {
    "id": "deploy",
    "execute-command": "/var/www/deploy.sh",
    "command-working-directory": "/var/www/yourdomain.com",
    "trigger-rule": {
      "match": {
        "type": "payload-hmac-sha256",
        "secret": "your-webhook-secret",
        "parameter": {
          "source": "header",
          "name": "X-Hub-Signature-256"
        }
      }
    }
  }
]
  

Start the webhook service:

  webhook -hooks /etc/webhook.conf -port 9000 -verbose &
  

3. Configure GitHub Webhook

  1. Go to your repo > Settings > Webhooks > Add webhook
  2. Payload URL: https://yourdomain.com:9000/hooks/deploy
  3. Content type: application/json
  4. Secret: same as in your webhook config
  5. Events: “Just the push event”
  6. Click Add webhook

Now every push to your repo triggers an automatic deployment.

Method 3: GitHub Actions (Most Reliable)

GitHub Actions can SSH into your server and deploy automatically on every push. This is the most flexible approach.

1. Add Server SSH Key to GitHub Secrets

  1. On your server, create a deploy key:

      ssh-keygen -t ed25519 -f ~/.ssh/deploy_key -C "github-actions"
    cat ~/.ssh/deploy_key.pub >> ~/.ssh/authorized_keys
    cat ~/.ssh/deploy_key   # copy the PRIVATE key
      
  2. In your GitHub repo, go to Settings > Secrets and variables > Actions

  3. Add these secrets:

    • SSH_PRIVATE_KEY – the private key content
    • SSH_HOST – your server’s IP or hostname
    • SSH_USER – the SSH username (usually root or a deploy user)

2. Create the Workflow

Create .github/workflows/deploy.yml in your repo:

  name: Deploy to Server

on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Deploy via SSH
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.SSH_HOST }}
          username: ${{ secrets.SSH_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /var/www/yourdomain.com
            git pull origin main
            npm install --production
            npm run build
            sudo systemctl restart nginx
  

3. Push and Watch

  git add .
git commit -m "Add deployment workflow"
git push origin main
  

Go to your repo’s Actions tab to see the workflow run. Green checkmark = deployed.

Advanced: Build on GitHub, Deploy Artifacts

For projects that need a build step (Next.js, Hugo, etc.), build on GitHub and deploy only the output:

  name: Build and Deploy

on:
  push:
    branches: [ main ]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install and Build
        run: |
          npm ci
          npm run build

      - name: Deploy to Server
        uses: burnett01/rsync-deployments@7
        with:
          switches: -avzr --delete
          path: dist/
          remote_path: /var/www/yourdomain.com/
          remote_host: ${{ secrets.SSH_HOST }}
          remote_user: ${{ secrets.SSH_USER }}
          remote_key: ${{ secrets.SSH_PRIVATE_KEY }}
  

This builds on GitHub’s infrastructure (fast and free) and only syncs the built files to your server.

Security Best Practices

  • Use a dedicated deploy user instead of root. Create a user with limited permissions:
      adduser deploy
    chown -R deploy:deploy /var/www/yourdomain.com
      
  • Use deploy keys (read-only) instead of personal access tokens
  • Never commit secrets to your repository. Use GitHub Secrets for sensitive values.
  • Restrict webhook access to GitHub’s IP ranges if possible
  • Log deployments so you can trace what was deployed and when

Which Method to Choose?

MethodBest ForComplexity
Git pullSolo developers, small projectsLow
WebhookSmall teams, simple projectsMedium
GitHub ActionsTeams, CI/CD pipelines, build stepsMedium-High

Last updated 19 Apr 2026, 23:46 +0300. history

Was this page helpful?