GitHub → Server (CI/CD Deploy via SSH)#
A. GitHub Actions Workflow (Deploy)#
Job (example: Django / Python)#
name: Deploy to Production
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy to Server
uses: appleboy/ssh-action@v1.0.0
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
port: 22
script: |
set -e
cd /var/www/Project1
git config --global --add safe.directory /var/www/Project1 || true
if [ ! -d .git ]; then
git init
git remote add origin git@github.com-Project1:${{ github.repository }}.git
git fetch origin
git checkout -b main origin/main
else
git fetch origin
git reset --hard origin/main
fi
source venv/bin/activate
pip install -r requirements.txt
python manage.py migrate --noinput
python manage.py collectstatic --noinput
sudo systemctl restart Project1.service
echo "Deployment completed successfully"
B. Server-side SSH Setup#
1️⃣ Key for GitHub Actions → Server access#
ssh-keygen -t ed25519 -C "github-actions-server-access" -f ~/.ssh/github_actions_key -N ""
cat ~/.ssh/github_actions_key.pub >> ~/.ssh/authorized_keys
- Private key → GitHub Secrets (
SSH_PRIVATE_KEY) - Public key → server
authorized_keys
2️⃣ Deploy key for Server → GitHub (git pull)#
ssh-keygen -t ed25519 -C "backend-deploy" -f ~/.ssh/backend_deploy_key -N ""
- Add PUBLIC key to GitHub repo → Deploy Keys (Read-only or Read/Write)
3️⃣ SSH config (MULTI-REPO PRO SETUP)#
# ~/.ssh/config
Host github.com-Project1
HostName github.com
User git
IdentityFile ~/.ssh/backend_deploy_key
IdentitiesOnly yes
StrictHostKeyChecking no
Host github.com-Project2
HostName github.com
User git
IdentityFile ~/.ssh/project2_deploy_key
IdentitiesOnly yes
StrictHostKeyChecking no
Permissions:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/config
ssh-keyscan github.com >> ~/.ssh/known_hosts
C. Git Setup on Server#
cd /var/www/Project1
git remote set-url origin git@github.com-Project1:ORG/Project1.git
git fetch origin
git checkout main
D. Why TWO keys? (important)#
| Purpose | Key | Reason |
|---|---|---|
| Actions → Server | github_actions_key |
Allows CI to SSH into server |
| Server → GitHub | backend_deploy_key |
Allows server to pull code |
✅ Least-privilege ✅ Clean revocation ✅ Multi-repo safe
Template note: Replace Project1, Project2, and service names per project.