如何用脚本自动部署项目到服务器?

wen 实用脚本 3

本文目录导读:

如何用脚本自动部署项目到服务器?

  1. 核心思路
  2. 方案一:Shell 脚本 + SSH (最基础、通用)
  3. 方案二:Git Hooks + 服务器端脚本 (常用)
  4. 核心补充:配置免密登录 (SSH Key)
  5. 高级优化建议
  6. 新手选择建议

这是一个非常实用的问题,自动部署脚本可以避免手动上传文件、手动执行命令等重复性工作,减少人为失误,下面我将介绍几种从简单到复杂的自动部署脚本方案。

核心思路

自动部署的流程通常包含以下几步:

  1. 连接服务器:通过 SSH 登录。
  2. 拉取代码:在服务器上执行 git pull 或从其他地方下载构建产物。
  3. 构建项目(如果需要):执行 npm run buildmvn package 等。
  4. 转移/更新文件:将构建产物复制到 Web 服务器(如 Nginx、Apache)的目录下。
  5. 重启服务:重启 Node.js 服务、Tomcat、Nginx 等,使新代码生效。
  6. 清理:删除临时文件。

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)自动通知你的部署服务器,拉取最新代码。

这两个方案都需要在服务器上配置 GitNode.js/Python/Java 等运行环境

1 使用 Webhook (最灵活)

  1. 在服务器上编写一个简单的 HTTP 服务(Node.js、Python Flask 等),监听一个 POST 请求。
  2. 当收到请求时,执行 git pullrestart 命令。
  3. 在 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。

  1. 本地或 CI 服务器:执行 ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
  2. 复制公钥到目标服务器ssh-copy-id user@your-server-ip (或手动将 ~/.ssh/id_rsa.pub 内容添加到服务器的 ~/.ssh/authorized_keys 文件)。

高级优化建议

  1. 使用 rsync 替代 scprsync 只传输差异文件,速度极快(尤其是大项目第二次部署时)。
  2. 使用 tar 打包:如果文件非常多(如 node_modules),先 tar -czf build.tar.gz dist/,再传输,可以提升速度。
  3. 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
  4. Zero-downtime 部署
    • nginx -s reload 是热重载(不中断服务)。
    • 对于 Node.js,使用 PM2 的 pm2 reload apppm2 restart

新手选择建议

  • 个人小项目/静态网站:方案一(本地 Shell 脚本 + rsync)足够,够简单。
  • 需要环境依赖的项目:方案二中的 GitHub Actions 是最佳选择,学习成本低,功能强大,你只需把项目传到 Git 仓库,剩下的脚本全自动跑。
  • 公司内部服务器/没有 CI 平台:方案一的 Webhook 是一个折中方案,但需要自己维护一个后台服务。

最核心的要点是:一定要把服务器密钥、密码存储在环境变量或 Secrets 中,绝对不要硬编码在脚本里

抱歉,评论功能暂时关闭!