DEV3 Technologies home

DEV3 Developer Forum

How do I deploy to a VPS from GitHub Actions over SSH securely?

DevOps helpSolved0 views
dev3 ·

I want every push to main to deploy my app to my server. I do not want to store my personal private key in the repo. What is a safe workflow?

#github-actions#deployment#ssh

0

1 reply

dev3 · Accepted answer

Create a dedicated deploy key pair, store the private half in GitHub Secrets, and give the matching user minimal rights on the server.

1. Generate a key just for CI

ssh-keygen -t ed25519 -f deploy_key -N "" -C "github-actions"

Append deploy_key.pub to ~/.ssh/authorized_keys of a deploy user on the server. Optionally restrict it in authorized_keys with command="/home/deploy/deploy.sh",no-port-forwarding,no-agent-forwarding,no-pty ssh-ed25519 AAAA....

2. Add repository secrets: SSH_PRIVATE_KEY (file contents), SSH_HOST, SSH_USER, and SSH_KNOWN_HOSTS (output of ssh-keyscan -t ed25519 your.host). Pinning known hosts prevents man in the middle attacks; avoid StrictHostKeyChecking no.

3. Workflow .github/workflows/deploy.yml:

name: Deploy
on:
  push:
    branches: [main]
concurrency: deploy-production

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Set up SSH
        run: |
          install -m 700 -d ~/.ssh
          echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519
          chmod 600 ~/.ssh/id_ed25519
          echo "${{ secrets.SSH_KNOWN_HOSTS }}" > ~/.ssh/known_hosts
      - name: Deploy
        run: ssh ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} 'bash /home/deploy/deploy.sh'

Keep the heavy lifting in a script on the server (pull, install, build, migrate, reload), so the workflow stays small. Build and test in a prior job and only deploy when it passes (needs:).

Tips

  • Use a GitHub Environment with required reviewers for production.
  • concurrency stops two deployments overlapping.
  • Pin third-party actions by version or commit hash.
  • Rotate the key if a collaborator with secrets access leaves.
0

Your reply

Every post is reviewed by DEV3 before it appears. Usually reviewed within 24 hours.

Markdown supported. Use ``` for code blocks. Images are not allowed.