本文目录导读:

这是一个非常实用的问题,自动部署脚本可以避免手动上传文件、手动执行命令等重复性工作,减少人为失误,下面我将介绍几种从简单到复杂的自动部署脚本方案。
核心思路
自动部署的流程通常包含以下几步:
- 连接服务器:通过 SSH 登录。
- 拉取代码:在服务器上执行
git pull或从其他地方下载构建产物。 - 构建项目(如果需要):执行
npm run build、mvn package等。 - 转移/更新文件:将构建产物复制到 Web 服务器(如 Nginx、Apache)的目录下。
- 重启服务:重启 Node.js 服务、Tomcat、Nginx 等,使新代码生效。
- 清理:删除临时文件。
Shell 脚本 + SSH (最基础、通用)
这是最直接的方式,适合前端项目(静态文件)或简单的后端服务。
场景:你在本地构建,然后将 dist 文件夹上传到服务器。
本地 deploy.sh 脚本:
#!/bin/bash
# 配置参数
SERVER_IP="你的服务器IP"
SSH_USER="你的SSH用户名"
REMOTE_PATH="/var/www/html" # 目标部署路径
LOCAL_DIST="./dist" # 本地构建输出目录
echo "===== 开始部署项目到 ${SERVER_IP} ====="
# 1. 在本地构建项目 (如果是前端项目)
echo ">>> 步骤1: 在本地构建项目..."
npm install
npm run build
if [ $? -ne 0 ]; then
echo "错误: 构建失败!"
exit 1
fi
# 2. 使用 rsync 上传文件到服务器 (比 scp 高效,只传输差异文件)
echo ">>> 步骤2: 上传文件到服务器..."
rsync -avz --delete ${LOCAL_DIST}/ ${SSH_USER}@${SERVER_IP}:${REMOTE_PATH}
# 3. 如果需要重启服务 (Node.js 应用)
# echo ">>> 步骤3: 重启服务器服务..."
# ssh ${SSH_USER}@${SERVER_IP} "pm2 restart all"
echo "===== 部署完成! ====="
执行:
chmod +x deploy.sh ./deploy.sh
优点:零依赖,任何 Linux/Mac 都能用。 缺点:需要在本地构建,若服务器上有很多依赖(如 PHP 扩展)可能不方便;每次都要本地跑脚本。
Git Hooks + 服务器端脚本 (常用)
用户在 git push 代码到远程仓库后,仓库服务器(如 GitHub/Gitea/GitLab)自动通知你的部署服务器,拉取最新代码。
这两个方案都需要在服务器上配置 Git 和 Node.js/Python/Java 等运行环境。
1 使用 Webhook (最灵活)
- 在服务器上编写一个简单的 HTTP 服务(Node.js、Python Flask 等),监听一个 POST 请求。
- 当收到请求时,执行
git pull和restart命令。 - 在 GitHub/GitLab 的项目设置中,添加一个 Webhook,URL 指向你的服务器服务。
一个简单的 Node.js Webhook 示例 (Linux):
// webhook-server.js
const express = require('express');
const { exec } = require('child_process');
const app = express();
app.use(express.json());
// 选择1: 直接拉取代码并部署
app.post('/deploy', (req, res) => {
console.log('收到部署请求:', req.body);
// 注意: 生产环境需要验证签名
exec('/usr/local/bin/deploy-project.sh', (error, stdout, stderr) => {
if (error) {
console.error(`执行错误: ${error}`);
res.status(500).send('部署失败');
return;
}
console.log(`stdout: ${stdout}`);
res.status(200).send('部署成功');
});
});
app.listen(3000, () => console.log('部署监听器运行在 3000 端口'));
对应的服务器脚本 /usr/local/bin/deploy-project.sh:
#!/bin/bash PROJECT_DIR="/path/to/your/project" cd $PROJECT_DIR git pull origin main npm install pm2 restart all
2 使用 GitHub Actions / GitLab CI (更强大、推荐)
这是目前最流行的方式,CI/CD 流水线可以在云端自动完成构建和部署。
GitHub Actions 示例 (.github/workflows/deploy.yml):
name: Deploy to Server
on:
push:
branches: [ main ] # 当 main 分支有推送时触发
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies & build
run: |
npm install
npm run build
- name: SSH into server and deploy
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd /path/to/your/project
git pull origin main
# 如果你已经在本步骤中构建了,这里可以只更新文件
cp -r /tmp/artifact/* /var/www/html/
sudo systemctl restart nginx # 或 pm2 restart
优点:全自动化、可审计、支持环境变量和密钥管理(通过 Secrets)。 缺点:需要学习平台配置。
核心补充:配置免密登录 (SSH Key)
无论哪种脚本,如果手动输入密码,自动化就失败了。 必须配置 SSH Key。
- 本地或 CI 服务器:执行
ssh-keygen -t rsa -b 4096 -C "your_email@example.com" - 复制公钥到目标服务器:
ssh-copy-id user@your-server-ip(或手动将~/.ssh/id_rsa.pub内容添加到服务器的~/.ssh/authorized_keys文件)。
高级优化建议
- 使用
rsync替代scp:rsync只传输差异文件,速度极快(尤其是大项目第二次部署时)。 - 使用
tar打包:如果文件非常多(如node_modules),先tar -czf build.tar.gz dist/,再传输,可以提升速度。 - Backup 与 Rollback:
- 在更新前将旧版本备份:
cp -r /var/www/html /var/www/html_backup_$(date +%Y%m%d%H%M%S) - 若部署失败,脚本中可以自动回滚:
mv /var/www/html /var/www/html_failed && mv /var/www/html_backup_xxx /var/www/html
- 在更新前将旧版本备份:
- Zero-downtime 部署:
nginx -s reload是热重载(不中断服务)。- 对于 Node.js,使用 PM2 的
pm2 reload app或pm2 restart。
新手选择建议
- 个人小项目/静态网站:方案一(本地 Shell 脚本 + rsync)足够,够简单。
- 需要环境依赖的项目:方案二中的 GitHub Actions 是最佳选择,学习成本低,功能强大,你只需把项目传到 Git 仓库,剩下的脚本全自动跑。
- 公司内部服务器/没有 CI 平台:方案一的 Webhook 是一个折中方案,但需要自己维护一个后台服务。
最核心的要点是:一定要把服务器密钥、密码存储在环境变量或 Secrets 中,绝对不要硬编码在脚本里。