— 2 min read
GitHub Action with EC2 using SSH
Deploy to an EC2 instance over SSH from a GitHub Actions workflow, without exposing long-lived credentials.
- GitHub
- AWS
- SSH
The simplest way to deploy to an EC2 instance from CI is to SSH in and run your deploy commands directly. No build servers, no extra infrastructure — just a workflow step that connects to the box and pulls the latest code.
1. Generate a deploy key
Create a dedicated SSH key pair for CI, rather than reusing your personal key:
ssh-keygen -t ed25519 -C "github-actions-deploy" -f deploy_key -N ""Add the public key (deploy_key.pub) to ~/.ssh/authorized_keys on the
EC2 instance, under whatever user will run the deploy (ec2-user, ubuntu,
or a dedicated service account).
2. Store the private key as a GitHub secret
In your repo, go to Settings → Secrets and variables → Actions and add:
EC2_SSH_KEY— the private key contents (deploy_key)EC2_HOST— the instance's public IP or DNS nameEC2_USER— the SSH user
3. Write the workflow
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy over SSH
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USER }}
key: ${{ secrets.EC2_SSH_KEY }}
script: |
cd /var/www/app
git pull origin main
npm ci
npm run build
pm2 restart appappleboy/ssh-action handles the connection and known-hosts handling for
you — no need to hand-roll ssh -i key.pem calls in the workflow itself.
Notes
- Restrict the EC2 security group's inbound SSH rule to GitHub's published IP ranges if you want to avoid opening port 22 to the world.
- If the deploy user needs
sudofor anything (restarting a system service, writing to/etc), configure passwordlesssudofor just that command viavisudo, rather than giving CI a fully privileged account. - Rotate the deploy key if it's ever exposed — it's cheap to regenerate and doesn't require touching anything else in the pipeline.