GitHub Actions是GitHub提供的CI/CD服务,可以在代码推送时自动执行构建、测试和部署。配合搬瓦工VPS,可以实现代码推送到GitHub后自动部署到服务器,省去手动SSH登录和执行部署命令的步骤。本文介绍完整的自动部署配置流程。
在本地生成专用于部署的SSH密钥对:
# 生成ED25519密钥对(推荐)
ssh-keygen -t ed25519 -C "github-actions-deploy" -f ~/.ssh/deploy_key
# 将公钥添加到VPS的authorized_keys
ssh-copy-id -i ~/.ssh/deploy_key.pub root@your-vps-ip
# 或手动复制
cat ~/.ssh/deploy_key.pub | ssh root@your-vps-ip "cat >> ~/.ssh/authorized_keys"
# 测试SSH登录
ssh -i ~/.ssh/deploy_key root@your-vps-ip
在GitHub仓库中存储敏感信息(密钥、服务器地址等),打开仓库页面,进入 Settings - Secrets and variables - Actions,添加以下Secrets:
VPS_HOST - VPS的IP地址或域名VPS_USER - SSH用户名(通常是root或deploy用户)VPS_SSH_KEY - SSH私钥内容(deploy_key文件的全部内容)VPS_PORT - SSH端口(搬瓦工默认随机端口)# 查看私钥内容(复制到GitHub Secrets)
cat ~/.ssh/deploy_key
Tip: 搬瓦工VPS的SSH端口不是默认的22,在KiwiVM面板中查看实际端口号。
在项目根目录创建 .github/workflows/deploy.yml:
Node.js应用部署示例:
name: Deploy to VPS
on:
push:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
- name: Build
run: npm run build
- name: Deploy to VPS
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.VPS_HOST }}
username: ${{ secrets.VPS_USER }}
key: ${{ secrets.VPS_SSH_KEY }}
port: ${{ secrets.VPS_PORT }}
script: |
cd /var/www/myapp
git pull origin main
npm ci --production
npm run build
pm2 reload myapp
Python应用部署示例:
name: Deploy Python App
on:
push:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Deploy via SSH
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.VPS_HOST }}
username: ${{ secrets.VPS_USER }}
key: ${{ secrets.VPS_SSH_KEY }}
port: ${{ secrets.VPS_PORT }}
script: |
cd /var/www/flask-app
git pull origin main
source venv/bin/activate
pip install -r requirements.txt
sudo systemctl restart flask-app
对于需要上传构建产物(而非在VPS上git pull)的场景:
name: Deploy with Rsync
on:
push:
branches: [ main ]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Build
run: |
npm ci
npm run build
- name: Deploy via Rsync
uses: burnett01/rsync-deployments@6
with:
switches: -avz --delete --exclude='node_modules' --exclude='.env'
path: ./
remote_path: /var/www/myapp/
remote_host: ${{ secrets.VPS_HOST }}
remote_user: ${{ secrets.VPS_USER }}
remote_key: ${{ secrets.VPS_SSH_KEY }}
remote_port: ${{ secrets.VPS_PORT }}
- name: Restart application
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.VPS_HOST }}
username: ${{ secrets.VPS_USER }}
key: ${{ secrets.VPS_SSH_KEY }}
port: ${{ secrets.VPS_PORT }}
script: |
cd /var/www/myapp
npm ci --production
pm2 reload myapp
name: Docker Deploy
on:
push:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build and deploy
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.VPS_HOST }}
username: ${{ secrets.VPS_USER }}
key: ${{ secrets.VPS_SSH_KEY }}
port: ${{ secrets.VPS_PORT }}
script: |
cd /var/www/myapp
git pull origin main
docker compose down
docker compose up -d --build
docker compose ps
部署完成后发送通知(以Telegram为例):
- name: Notify on success
if: success()
run: |
curl -s -X POST "https://api.telegram.org/bot${{ secrets.TG_BOT_TOKEN }}/sendMessage" \
-d "chat_id=${{ secrets.TG_CHAT_ID }}" \
-d "text=Deploy succeeded: ${{ github.repository }} @ ${{ github.sha }}"
- name: Notify on failure
if: failure()
run: |
curl -s -X POST "https://api.telegram.org/bot${{ secrets.TG_BOT_TOKEN }}/sendMessage" \
-d "chat_id=${{ secrets.TG_CHAT_ID }}" \
-d "text=Deploy FAILED: ${{ github.repository }} @ ${{ github.sha }}"
StrictHostKeyChecking=noTip: 更多教程请查看新手教程。