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-agentand 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.
--deleteprunes removed files but also anything on the server not indist/.- Deploy to a release directory and swap a symlink for an atomic switch.
Related guides
How to Do Atomic Deploys for a Static Site From CIDeploy a static site atomically by uploading a new versioned directory and flipping a symlink or pointer, so…
How to Deploy Only When the Site Actually ChangedSkip a static site deploy when nothing that affects the build changed, using a paths filter or a content hash…