Skip to content
Latchkey

How to Deploy a Static Site to Your Own Server Over SSH From CI

rsync over SSH copies only the changed files from the build to the server web root using a deploy key from CI secrets.

Load a private deploy key from a secret into the SSH agent, add the host to known_hosts, then run rsync -az --delete dist/ user@host:/var/www/site/ to publish the build.

Steps

  • Generate a deploy keypair and add the public key to the server.
  • Store the private key as a CI secret.
  • Load it with webfactory/ssh-agent and pin the host key.
  • rsync the build directory to the web root with --delete.

Workflow

.github/workflows/ci.yml
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm run build
      - uses: webfactory/ssh-agent@v0.9.0
        with:
          ssh-private-key: ${{ secrets.DEPLOY_KEY }}
      - run: ssh-keyscan -H $DEPLOY_HOST >> ~/.ssh/known_hosts
        env:
          DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
      - run: rsync -az --delete dist/ deploy@${{ secrets.DEPLOY_HOST }}:/var/www/site/

Gotchas

  • Without pinning the host key via ssh-keyscan, rsync prompts and hangs the job.
  • --delete prunes removed files but also anything on the server not in dist/.
  • Deploy to a release directory and swap a symlink for an atomic switch.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →