Perfect — we can make a fully generic GitHub Actions → VPS deployment guide that works for any project type. This will give you a reference for future projects, and you can just plug in a project-specific deploy.sh and optionally generate a workflow YAML using an LLM.
Here’s the generic guide:
Generic GitHub Actions → VPS Deployment Guide
Step 1 — Generate SSH Key for GitHub Actions
On your local machine:
1
| ssh-keygen -t rsa -b 4096 -f deploy_key -C "github-action-deploy"
|
This creates:
deploy_key → private key (keep secret)deploy_key.pub → public key
Do not upload the private key publicly.
Step 2 — Add Public Key to VPS
- Copy the public key:
1
2
| type deploy_key.pub # Windows
cat deploy_key.pub # Linux/macOS
|
- On your VPS, add it to the deploy user’s authorized keys:
1
2
3
4
| mkdir -p ~/.ssh
echo "PASTE_PUBLIC_KEY_HERE" >> ~/.ssh/authorized_keys
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
|
- Test SSH access with:
1
| ssh -i "deploy_key" user@vps.example.com
|
Step 3 — Add GitHub Secrets
Go to GitHub → Repo → Settings → Secrets and Variables → Actions → New repository secret:
| Secret Name | Value |
|---|
DEPLOY_SSH_KEY | contents of deploy_key (private key) |
VPS_HOST | VPS IP or domain |
VPS_USER | SSH username |
VPS_PORT | SSH port (default: 22) |
KNOWN_HOSTS | host key (see next step) |
Step 4 — Generate known_hosts
1
| ssh-keyscan -t rsa -p 22 vps.example.com > known_hosts
|
- Open
known_hosts and copy the line starting with vps.example.com ssh-rsa ... - Add it to GitHub secrets as
KNOWN_HOSTS.
Step 5 — Prepare Folder on VPS
1
2
| ssh -i "deploy_key" user@vps.example.com
mkdir -p ~/Projects/my_project
|
- Replace
~/Projects/my_project with the folder where you want your project deployed.
Step 6 — Create Generic deploy.sh Script
1
| nano ~/Projects/my_project/deploy.sh
|
Example generic script:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| #!/usr/bin/env bash
set -e
echo "🚀 Starting deployment..."
cd ~/Projects/my_project
# --- Run project-specific deploy commands ---
# Examples:
# - Install dependencies
# - Build project
# - Restart service
# These are placeholders — customize per project
echo "✅ Deployment completed successfully!"
|
Make it executable:
1
| chmod +x ~/Projects/my_project/deploy.sh
|
In future projects, replace the placeholders with project-specific commands (Node, Python, Docker, etc.).
Step 7 — Install rsync on VPS
1
2
| apt update
apt install -y rsync
|
Required for GitHub Actions to upload files.
Step 8 — Create GitHub Actions Workflow
- Create file:
1
2
| mkdir -p .github/workflows
nano .github/workflows/deploy.yml
|
- Paste generic workflow:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
| name: Deploy to VPS
on:
push:
branches: [ "main" ] # change branch if needed
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Start SSH agent and add key
uses: webfactory/ssh-agent@v0.9.1
with:
ssh-private-key: $
- name: Add known_hosts
run: |
mkdir -p ~/.ssh
echo "$" > ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
- name: Copy files to VPS
run: |
rsync -avz --delete --exclude='.git' ./ $@$:~/Projects/my_project/
env:
RSYNC_RSH: "ssh -p $ -o StrictHostKeyChecking=yes"
- name: Run remote deploy script
run: |
ssh -p $ $@$ "cd ~/Projects/my_project && ./deploy.sh || echo 'No deploy.sh found'"
|
- Commit and push:
1
2
3
| git add .github/workflows/deploy.yml
git commit -m "Add generic deploy workflow"
git push origin main
|
Step 9 — Test Deployment
- Go to GitHub → Actions tab → confirm workflow runs automatically on push.
Check logs:
- rsync uploads files
- deploy.sh executes on VPS
Step 10 — Customizing for Future Projects
Replace deploy.sh contents with project-specific commands:
- Node.js:
npm install, npm run build, pm2 restart - Python:
pip install -r requirements.txt, systemctl restart service - Docker:
docker-compose pull && docker-compose up -d
Update workflow YAML only if:
- Project folder changes
- You need extra environment variables
- You want additional steps (tests, linting, etc.)
Step 11 — Optional: PM2 or systemd service
- For long-running apps (Node, Python), configure PM2 or systemd to restart your app after reboot.
- Example PM2 setup:
1
2
3
4
| npm install -g pm2
pm2 start server.js --name my_project
pm2 startup systemd
pm2 save
|
Step 12 — Troubleshooting
| Error | Solution |
|---|
Permission denied (publickey) | Check DEPLOY_SSH_KEY and authorized_keys on VPS |
Host key verification failed | Verify KNOWN_HOSTS matches ssh-keyscan output |
rsync: command not found | Install rsync on VPS: apt install -y rsync |
deploy.sh not found | Ensure it exists in the VPS folder and is executable (chmod +x deploy.sh) |