How to Set Up Continuous Deployment for a Static Site with GitHub Actions

Automating static site deployment on every Git push eliminates manual build/upload steps and ensures your live site always reflects your latest committed changes. This guide covers setting this up with GitHub Actions.

Why Automate Static Site Deployment

See How to Set Up Automatic Static Site Deployment from Git for the general webhook-based pattern — GitHub Actions provides a more integrated, feature-rich alternative, particularly valuable if your build process involves multiple steps (linting, testing, building) beyond a simple file copy.

Step 1 — Create the Workflow File

mkdir -p .github/workflows
nano .github/workflows/deploy.yml

Step 2 — Define the Build and Deploy Workflow

name: Deploy Static Site
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm install
      - run: npm run build
      - name: Deploy to VPS
        uses: appleboy/[email protected]
        with:
          host: ${{ secrets.VPS_HOST }}
          username: ${{ secrets.VPS_USER }}
          key: ${{ secrets.VPS_SSH_KEY }}
          source: "dist/*"
          target: "/var/www/mysite"

Builds the site, then securely copies the output to your VPS via SSH — see How to Manage Secrets in a CI/CD Pipeline for properly configuring the required secrets.

Step 3 — Set Up Required Secrets in GitHub

In repository Settings > Secrets and variables > Actions, add VPS_HOST, VPS_USER, and VPS_SSH_KEY — never hardcode these values directly in the workflow file.

Step 4 — Create a Dedicated Deployment SSH Key

See How to Set Up a Deployment User with Restricted SSH Access — use a dedicated key/user with minimal necessary permissions for the deployment target directory only, rather than a broadly-privileged account.

Adding a Build Verification Step

- name: Check for broken links
  run: npx linkinator dist --recurse

Consider adding basic verification steps (broken link checking, HTML validation) before deployment, catching issues before they reach your live site.

Setting Up Preview Deployments for Pull Requests

See How to Set Up Preview Deployments for Pull Requests — extend this workflow pattern to also deploy PR branches to a temporary preview location, letting you review changes before merging to main.

Notifying on Deployment Success/Failure

- name: Notify on failure
  if: failure()
  run: curl -X POST YOUR_WEBHOOK_URL -d "Deployment failed"

Reloading Nginx After File Updates (If Needed)

- name: Reload Nginx
  uses: appleboy/[email protected]
  with:
    host: ${{ secrets.VPS_HOST }}
    script: sudo systemctl reload nginx

Usually unnecessary for pure static files (Nginx serves updated files immediately), but relevant if your deployment also touches Nginx configuration.

Common Errors

SCP/SSH action fails with permission denied — verify the deployment user's SSH key is correctly added to the target server's authorized_keys, and that the target directory has appropriate write permissions for that user.

Continue Reading

Browse more articles in Static Site Hosting & Frontend Deployment.

  • github actions static site deploy, continuous deployment static site, scp deploy github actions, automated static site build
  • 0 Kunder som kunne bruge dette svar
Hjalp dette svar dig?

Relaterede artikler

How to Host a Static Website on a VPS with Nginx

Static websites — plain HTML, CSS, and JavaScript with no server-side processing —...

How to Deploy a Next.js Application on a VPS

Next.js supports several deployment modes — fully static export, server-side rendering with...

How to Deploy a Static Site Built with Astro, Hugo, or Jekyll

Static site generators (Astro, Hugo, Jekyll) produce plain HTML/CSS/JS at build time —...

How to Optimize Images for Web Performance

Images are typically the largest contributor to page weight and load time. This guide covers...

How to Set Up a Jamstack Site with a Headless CMS Backend

The Jamstack architecture (JavaScript, APIs, Markup) combines a pre-built static frontend with a...