C.W.K.
Stream
Lesson 06 of 13 · published

SSH Deployment

~10 min · ssh, vps, rsync

Level 0Apprentice
0 XP0/101 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

The pragmatic single-server pipeline

Not every project lives on a managed cloud platform. For VPS deployments, self-hosted servers, fleet management, or homelab work, SSH-based deploy is honest and reliable. The pattern:

  1. Store an SSH private key as a repo secret.
  2. In CI, write the key to a temp file with strict perms.
  3. Connect via ssh or rsync; run a deploy script.

Or use a packaged action: appleboy/ssh-action for command execution, burnett01/rsync-deployments for file sync.

SSH key hygiene

  • Generate a new key just for CI — don't reuse your personal key.
  • Restrict the authorized_keys entry on the target with command="...", from="github-runner-ip-range", or both.
  • Rotate quarterly.
  • Add the host to ~/.ssh/known_hosts in CI to prevent MITM.

Code

rsync deploy with SSH key from secret·yaml
  deploy:
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/checkout@v4
      - run: ./build.sh
      - name: Setup SSH
        run: |
          umask 077
          mkdir -p ~/.ssh
          printf '%s\n' "${{ secrets.DEPLOY_SSH_KEY }}" > ~/.ssh/id_ed25519
          ssh-keyscan -H ${{ vars.DEPLOY_HOST }} >> ~/.ssh/known_hosts
      - name: Sync
        run: |
          rsync -av --delete ./dist/ \
            deploy@${{ vars.DEPLOY_HOST }}:/var/www/example/
      - name: Run deploy script remotely
        run: |
          ssh deploy@${{ vars.DEPLOY_HOST }} 'sudo systemctl reload nginx'

External links

Exercise

If you have any VPS deploy that currently uses your personal SSH key, generate a deploy-only key, restrict it on the target with command=, and migrate the workflow to use it.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.