Tutorials

Getting Started with GitHub Actions: Automate Your Website Deployments

Muhammad SaadApril 17, 20266 min read
Getting Started with GitHub Actions: Automate Your Website Deployments

Every time you push code, you SSH into your server, pull the latest changes, restart services, and hope nothing breaks. Sound familiar? There's a better way.

GitHub Actions lets you automate your entire deployment pipeline — from running tests to deploying code — every time you push to your repository. No more manual deployments, no more forgotten steps, no more "it works on my machine" problems.

Here's how to set it up from scratch.

What Are GitHub Actions?

GitHub Actions is a CI/CD (Continuous Integration / Continuous Deployment) platform built directly into GitHub. You define workflows in YAML files, and GitHub runs them automatically based on triggers like pushing code, opening pull requests, or on a schedule.

Push to main → Run tests → Build → Deploy to server

The best part? It's free for public repositories and includes 2,000 minutes per month for private repos on the free tier.

Your First Deployment Workflow

Let's build a real workflow that deploys a website to a VPS whenever you push to the main branch.

Step 1: Create the Workflow File

In your repository, create .github/workflows/deploy.yml:

name: Deploy to Production

on:
  push:
    branches: [main]

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

      - name: Deploy to server
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /var/www/mysite
            git pull origin main
            npm install --production
            npm run build
            pm2 restart myapp

Step 2: Add Repository Secrets

Never hardcode credentials. Go to your GitHub repo → Settings → Secrets and variables → Actions, and add:

  • SERVER_HOST — Your server's IP address (e.g., 203.0.113.50)
  • SERVER_USER — SSH username (e.g., deploy)
  • SSH_PRIVATE_KEY — Your private SSH key

To generate a deployment key:

ssh-keygen -t ed25519 -C "github-actions-deploy" -f ~/.ssh/deploy_key

Add the public key to your server's ~/.ssh/authorized_keys and paste the private key into the GitHub secret.

Step 3: Push and Watch

Commit the workflow file and push to main. Go to the "Actions" tab in your repo to watch the deployment run in real time.

Adding Tests Before Deployment

Deploying untested code is risky. Add a test step that runs before deployment:

name: Test and Deploy

on:
  push:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Run tests
        run: npm test

  deploy:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Deploy to server
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /var/www/mysite
            git pull origin main
            npm install --production
            npm run build
            pm2 restart myapp

The needs: test directive ensures deployment only happens after all tests pass.

WordPress Deployment Workflow

For WordPress sites, the workflow looks slightly different:

name: Deploy WordPress Theme

on:
  push:
    branches: [main]

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

      - name: Deploy theme via rsync
        uses: burnett01/rsync-deployments@6.0.0
        with:
          switches: -avzr --delete --exclude='.git' --exclude='.github'
          path: wp-content/themes/mytheme/
          remote_path: /var/www/mysite/wp-content/themes/mytheme/
          remote_host: ${{ secrets.SERVER_HOST }}
          remote_user: ${{ secrets.SERVER_USER }}
          remote_key: ${{ secrets.SSH_PRIVATE_KEY }}

Rsync only transfers changed files, making deployments fast and efficient.

Laravel Deployment

Laravel projects need a few extra steps:

name: Deploy Laravel

on:
  push:
    branches: [main]

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

      - name: Deploy to server
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /var/www/mylaravel
            git pull origin main
            composer install --no-dev --optimize-autoloader
            php artisan migrate --force
            php artisan config:cache
            php artisan route:cache
            php artisan view:cache
            sudo systemctl reload php8.2-fpm

Deployment Notifications

Get notified when deployments succeed or fail. Add a Slack or Discord notification step:

      - name: Notify on success
        if: success()
        run: |
          curl -X POST "${{ secrets.DISCORD_WEBHOOK }}" \
            -H "Content-Type: application/json" \
            -d '{"content": "✅ Deployment successful: ${{ github.repository }} (${{ github.sha }})"}'

      - name: Notify on failure
        if: failure()
        run: |
          curl -X POST "${{ secrets.DISCORD_WEBHOOK }}" \
            -H "Content-Type: application/json" \
            -d '{"content": "❌ Deployment FAILED: ${{ github.repository }} — check Actions tab"}'

Best Practices

Use Environment Protection Rules

For production deployments, enable environment protection in GitHub:

  1. Go to Settings → Environments → New environment → "production"
  2. Add required reviewers (optional — someone must approve before deploy)
  3. Restrict to main branch only

Keep Secrets Secure

  • Never echo secrets in logs
  • Rotate SSH keys periodically
  • Use deploy-specific keys with limited permissions
  • Consider using OIDC for cloud providers instead of long-lived keys

Handle Rollbacks

Add a manual rollback workflow:

name: Rollback

on:
  workflow_dispatch:
    inputs:
      commit_sha:
        description: 'Commit SHA to rollback to'
        required: true

jobs:
  rollback:
    runs-on: ubuntu-latest
    steps:
      - name: Rollback deployment
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /var/www/mysite
            git fetch origin
            git checkout ${{ github.event.inputs.commit_sha }}
            npm install --production
            npm run build
            pm2 restart myapp

Trigger this manually from the Actions tab when you need to revert a bad deploy.

Common Pitfalls to Avoid

🚩 No test step — Always test before deploying. A broken deployment takes your site down.

🚩 Root SSH access — Create a dedicated deploy user with limited permissions.

🚩 No timeout — Add timeout-minutes: 10 to your jobs to prevent hung deployments.

🚩 Deploying on every push — Only deploy from your main branch. Use pull requests for code review.

🚩 No notification on failure — If you don't know a deployment failed, you can't fix it.

Automate Your Deployments with DeployBase

GitHub Actions handles the CI/CD pipeline, but you still need reliable infrastructure to deploy to. At DeployBase, our VPS plans come with full SSH access, pre-installed Git, and the performance your applications need. Starting at $5/month with NVMe SSD storage, automated backups, and 24/7 support.

Pair GitHub Actions with DeployBase hosting and you get a professional deployment pipeline that rivals setups costing ten times as much.

Get your VPS at DeployBase → — reliable hosting for automated deployments.

Share this article

Muhammad Saad

Muhammad Saad

DeployBase Team

Ready to Get Started?

Join thousands of developers who trust DeployBase for their hosting needs.