This project uses GitHub Actions to automatically deploy your app to a remote server whenever:
- code is pushed to
main - or the nightly schedule runs
Deployment happens through SSH, so GitHub securely connects to your server and runs commands like:
git pull origin main
docker compose up -d --buildPush to main
↓
GitHub Actions runs
↓
SSH into server
↓
Pull latest code
↓
Restart app
Before starting, you need:
- Ubuntu/Linux server (VPS or VM)
- Git installed
- Your project already cloned on server
- Docker / Node / Python (depending on your stack)
- GitHub repo
You need a dedicated SSH key for GitHub Actions (NOT your personal one).
On your local machine run:
ssh-keygen -t ed25519 -C "github-deploy" -f github-deploy-keyPress Enter for no password.
This creates:
github-deploy-key ← private key (SECRET)
github-deploy-key.pub ← public key (SAFE)
Copy the public key:
cat github-deploy-key.pubOn your server:
mkdir -p ~/.ssh
nano ~/.ssh/authorized_keysPaste the public key.
Then fix permissions:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keysGo to your repository:
Settings → Secrets and variables → Actions → New repository secret
Your server IP
123.45.67.89
Your SSH user
ubuntu
or
root
Paste PRIVATE key content
cat github-deploy-keyCopy EVERYTHING including:
-----BEGIN OPENSSH PRIVATE KEY-----
...
-----END OPENSSH PRIVATE KEY-----
Path to project on server
Example:
/var/www/myapp
Create:
.github/workflows/deploy.yml
Paste your workflow file there.
Folder structure:
project/
├─ .github/
│ └─ workflows/
│ └─ deploy.yml
├─ src/
├─ docker-compose.yml
└─ README.md
Push to main:
git add .
git commit -m "test deploy"
git push origin mainThen:
GitHub → Actions tab
You should see:
✓ Deploy to Server
✓ Deployment finished successfully
Inside workflow SSH script you can run:
docker compose down
docker compose up -d --buildnpm install
npm run build
pm2 restart allpip install -r requirements.txt
sudo systemctl restart appFix:
chmod 600 ~/.ssh/authorized_keys
chmod 700 ~/.sshAdd:
ssh youruser@server-ipAccept fingerprint once.
Check:
- No spaces
- Private key includes BEGIN/END lines
- Secret names match exactly
✔ Use separate deploy key ✔ Do NOT reuse personal SSH key ✔ Do NOT commit private key ✔ Limit server user permissions ✔ Prefer non-root user
Now every push to main automatically deploys 🚀