{T}

rsync与GitHooks自动化部署实战

rsync与GitHooks自动化部署实战

学习目标:掌握 rsync 文件同步、Git Hooks 自动化、Husky 工具使用、SSH 免密登录、自动化部署脚本编写。


一、自动化部署方案对比

1.1 个人开发者部署需求

code
个人开发者 vs 团队部署需求:
│
├── 团队部署(CI/CD)
│   ├── GitHub Actions / GitLab CI
│   ├── 自动化流水线
│   ├── 复杂权限管理
│   ├── 多环境部署
│   └── 适用:团队协作、企业项目
│
└── 个人部署(Git Hooks)
    ├── 本地脚本自动化
    ├── 无需第三方服务
    ├── 代码不外泄
    ├── 快速迭代部署
    └── 适用:个人项目、小型站点

1.2 rsync + Git Hooks 方案优势

code
自动化部署方案优势:
│
├── 1. 自动化 
│   ├── Git commit 自动触发
│   ├── 无需手动上传
│   └── 一键部署
│
├── 2. 安全性 
│   ├── 代码无需上传第三方平台
│   ├── SSH 加密传输
│   └── 密钥认证
│
├── 3. 高效性 
│   ├── 增量同步(只传输变化文件)
│   ├── 压缩传输
│   └── 速度快
│
├── 4. 低成本 
│   ├── 无需 CI/CD 服务
│   ├── 无需额外费用
│   └── 配置简单
│
└── 5. 灵活性 
    ├── 自定义部署脚本
    ├── 可扩展远程命令
    └── 适配多种场景

二、rsync 命令详解

2.1 rsync 简介

rsync(remote sync)是一个高效的文件同步和传输工具。

code
rsync 核心特性:
│
├── 1. 增量同步 
│   ├── 只传输变化的文件
│   ├── 节省带宽和时间
│   └── 算法:滚动校验和
│
├── 2. 保持文件属性 
│   ├── 权限(-p)
│   ├── 时间戳(-t)
│   ├── 所有者(-o)
│   └── 组(-g)
│
├── 3. 压缩传输 
│   ├── -z 参数压缩
│   ├── 减少传输数据量
│   └── 适合慢速网络
│
├── 4. 安全传输 
│   ├── 支持 SSH 协议
│   ├── 加密传输
│   └── 密钥认证
│
└── 5. 灵活过滤 
    ├── --exclude 排除文件
    ├── --include 包含文件
    └── --delete 删除目标多余文件

2.2 rsync 安装

macOS

bash
# macOS 默认自带 rsync,但版本较老
# 推荐使用 Homebrew 安装最新版本
brew install rsync

# 验证安装
rsync --version

Linux(Ubuntu/Debian)

bash
# Ubuntu 22.04 默认已安装
# 如果没有,使用 apt 安装
sudo apt update
sudo apt install rsync -y

# 验证安装
rsync --version

Linux(CentOS/RHEL)

bash
# 使用 yum 安装
sudo yum install rsync -y

# 验证安装
rsync --version

Windows

code
Windows 解决方案:
│
├── 方案一:WSL(推荐)
│   ├── 安装 WSL2
│   ├── 安装 Ubuntu 子系统
│   └── 在 WSL 中使用 rsync
│
├── 方案二:虚拟机 
│   ├── 安装 VirtualBox
│   ├── 安装 Ubuntu 虚拟机
│   └── 在虚拟机中开发部署
│
└── 方案三:云服务器 
    ├── 购买云服务器
    ├── 直接在服务器上操作
    └── 最接近生产环境

2.3 rsync 基础语法

bash
# 基础语法
rsync [选项] 源路径 目标路径

# 本地同步
rsync -av /source/ /destination/

# 本地 → 远程(上传)
rsync -avz -e ssh /local/path/ user@remote:/remote/path/

# 远程 → 本地(下载)
rsync -avz -e ssh user@remote:/remote/path/ /local/path/

2.4 rsync 常用参数详解

参数说明示例重要程度
-a归档模式(保留权限、时间戳等)rsync -a src/ dst/
-v显示详细信息rsync -av src/ dst/
-z压缩传输rsync -az src/ dst/
-h人性化显示(KB/MB)rsync -ah src/ dst/
-e指定远程 shellrsync -e ssh src/ user@host:/dst/
--delete删除目标多余文件rsync -av --delete src/ dst/
--exclude排除文件rsync -av --exclude '*.log' src/ dst/
--include包含文件rsync -av --include '*.js' src/ dst/
--progress显示进度rsync -av --progress src/ dst/
-P等同于 --progress --partialrsync -avP src/ dst/

2.5 rsync 实战示例

基础同步

bash
# 本地目录同步
rsync -av /Users/project/dist/ /backup/dist/

# 输出解释:
# -a: 保留文件属性
# -v: 显示详细过程
# 源路径末尾的 / 表示同步目录内容(不包括目录本身)

上传到远程服务器

bash
# 完整命令示例
rsync -avz \
  -e 'ssh -p 22' \
  --delete \
  ./dist/ \
  root@192.168.31.77:/home/website/project/

# 参数说明:
# -avz: 归档 + 详细 + 压缩
# -e 'ssh -p 22': 使用 SSH 协议,端口 22
# --delete: 删除服务器上多余的文件
# ./dist/: 本地构建产物目录
# root@192.168.31.77:/home/website/project/: 远程服务器路径

使用 SSH Config 别名

bash
# 配置好 ~/.ssh/config 后,可以简化命令
rsync -avz --delete ./dist/ ubuntu:/var/www/project/

# ubuntu 是 ~/.ssh/config 中配置的 Host 别名

排除特定文件

bash
# 排除 .git 目录和 node_modules
rsync -avz \
  --exclude '.git' \
  --exclude 'node_modules' \
  --exclude '*.log' \
  ./project/ \
  user@remote:/var/www/project/

三、Git Hooks 与 Husky

3.1 Git Hooks 简介

code
Git Hooks 工作原理:
│
├── 什么是 Git Hooks?
│   ├── Git 提供的钩子机制
│   ├── 在特定事件触发时执行脚本
│   └── 位置:.git/hooks/ 目录
│
├── 常用 Hooks
│   ├── pre-commit:提交前执行
│   ├── pre-push:推送前执行
│   ├── post-merge:合并后执行
│   └── commit-msg:提交信息验证
│
└── 问题
    ├── .git/hooks/ 不纳入版本控制
    ├── 团队共享困难
    └── 手动配置繁琐

3.2 Husky 工具

Husky 是现代化的 Git Hooks 管理工具。

code
Husky 优势:
│
├── 1. 版本控制 
│   ├── 配置文件纳入 Git
│   ├── 团队共享配置
│   └── 一致性保证
│
├── 2. 简化配置 
│   ├── npm install 自动设置
│   ├── 无需手动创建钩子
│   └── 命令简单直观
│
└── 3. 跨平台 
    ├── 支持 macOS/Linux/Windows
    └── 统一的配置方式

3.3 Husky 安装与配置

第一步:初始化 Git 仓库

bash
# 初始化 Git 仓库
git init

# 或克隆现有项目
git clone <repository-url>

第二步:安装 Husky

bash
# 使用 pnpm 安装(推荐)
pnpm add -D husky

# 或使用 npm
npm install --save-dev husky

# 或使用 yarn
yarn add --dev husky

第三步:初始化 Husky

bash
# 初始化 Husky
npx husky install

# 输出:
# husky - Git hooks installed

# 这会创建 .husky 目录

第四步:配置 package.json

json
{
  "scripts": {
    "prepare": "husky install"
  }
}

说明

  • prepare 脚本会在 npm install 后自动执行
  • 确保团队成员安装依赖时自动设置 Husky

第五步:创建 Git Hook

bash
# 创建 pre-commit hook
npx husky add .husky/pre-commit "npm test"

# 或手动创建
echo "npm test" > .husky/pre-commit

# 输出示例:
# husky - created .husky/pre-commit

第六步:测试 Hook

bash
# 添加文件到暂存区
git add .

# 提交
git commit -m "test commit"

# pre-commit hook 会自动执行 npm test

3.4 Husky 常用 Hooks 配置

bash
# pre-commit:提交前执行
npx husky add .husky/pre-commit "npm run lint"

# commit-msg:提交信息验证
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"'

# pre-push:推送前执行测试
npx husky add .husky/pre-push "npm run test"

# 添加多个命令
npx husky add .husky/pre-commit "npm run lint && npm run test"

四、自动化部署脚本编写

4.1 完整部署流程

code
自动化部署流程:
│
├── 第一步:功能开发
│   └── 编写代码、本地测试
│
├── 第二步:Git 提交 
│   ├── git add .
│   ├── git commit -m "message"
│   └── 触发 pre-commit hook
│
├── 第三步:自动构建 
│   ├── Husky 执行 deploy.sh
│   ├── npm run build
│   └── 生成 dist 目录
│
├── 第四步:自动上传 
│   ├── rsync 同步文件
│   ├── 增量传输
│   └── 压缩传输
│
└── 第五步:部署完成
    ├── 服务器文件更新
    ├── 站点自动更新
    └── 无需手动操作

4.2 deploy.sh 脚本详解

创建脚本文件

bash
# 在项目根目录创建脚本
touch deploy.sh

# 赋予执行权限
chmod +x deploy.sh

完整脚本内容

bash
#!/bin/bash

# ==================== 自动化部署脚本 ====================
# 功能:自动构建并部署到远程服务器
# 作者:Your Name
# 日期:2024-01-01

# 颜色输出
GREEN='\033[0;32m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 配置变量(根据实际情况修改)
REMOTE_HOST="ubuntu"              # 远程服务器别名(~/.ssh/config)
REMOTE_USER="root"                # 远程用户
REMOTE_PATH="/var/www/project"    # 远程部署路径
LOCAL_BUILD_DIR="./dist"          # 本地构建产物目录
SSH_PORT="22"                     # SSH 端口

# ==================== 第一步:构建项目 ====================
echo -e "${BLUE}[1/3] 开始构建项目...${NC}"
npm run build

# 检查构建是否成功
if [ $? -ne 0 ]; then
    echo -e "${RED}构建失败!${NC}"
    exit 1
fi

echo -e "${GREEN} 构建完成${NC}"

# ==================== 第二步:同步文件到服务器 ====================
echo -e "${BLUE}[2/3] 开始同步文件到服务器...${NC}"

# rsync 命令详解:
# -a: 归档模式(保留权限、时间戳等)
# -v: 显示详细信息
# -z: 压缩传输
# --delete: 删除目标多余文件
# -e: 指定远程 shell(SSH)

rsync -avz \
  --delete \
  -e "ssh -p ${SSH_PORT}" \
  ${LOCAL_BUILD_DIR}/ \
  ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_PATH}/

# 检查同步是否成功
if [ $? -ne 0 ]; then
    echo -e "${RED}文件同步失败!${NC}"
    exit 1
fi

echo -e "${GREEN} 文件同步完成${NC}"

# ==================== 第三步:执行远程命令(可选) ====================
echo -e "${BLUE}[3/3] 执行远程命令...${NC}"

# 示例:重启 Nginx、清理缓存等
ssh ${REMOTE_USER}@${REMOTE_HOST} << 'EOF'
  # 重启 Nginx(如果需要)
  # sudo systemctl restart nginx

  # 设置文件权限
  # chown -R www-data:www-data /var/www/project

  # 清理缓存(如果有)
  # rm -rf /var/www/project/cache/*

  echo "远程命令执行完成"
EOF

echo -e "${GREEN} 部署完成!${NC}"

脚本关键点说明

部分说明注意事项
#!/bin/bashShebang,指定解释器必须在第一行
npm run build构建项目确保 package.json 中有 build 脚本
rsync -avz --delete同步文件--delete 会删除服务器上多余文件
${LOCAL_BUILD_DIR}/源路径末尾的 /同步目录内容,不包括目录本身
ssh 远程命令执行远程操作可选,用于重启服务等

4.3 配置 Husky 触发脚本

方法一:直接执行脚本

bash
# .husky/pre-commit
./deploy.sh

方法二:获取当前目录(推荐)

bash
# .husky/pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

# 获取项目根目录
PROJECT_ROOT=$(git rev-parse --show-toplevel)

# 执行部署脚本
${PROJECT_ROOT}/deploy.sh

方法三:添加条件判断

bash
# .husky/pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

# 只在 main 分支执行部署
current_branch=$(git symbolic-ref --short HEAD)

if [ "$current_branch" = "main" ]; then
  echo "部署到生产环境..."
  ./deploy.sh
else
  echo "当前分支:$current_branch,跳过部署"
fi

五、SSH 免密登录配置

5.1 为什么需要 SSH 免密登录?

code
SSH 免密登录的必要性:
│
├── 问题:每次部署需要输入密码
│   ├── 手动输入密码繁琐
│   ├── 脚本无法自动执行
│   └── 效率低下
│
└── 解决:SSH 密钥认证 
    ├── 一次配置,永久使用
    ├── 脚本自动执行
    └── 安全性高(密钥比密码更安全)

5.2 SSH 密钥生成

bash
# 生成 SSH 密钥对
ssh-keygen -t ed25519 -C "your_email@example.com"

# 或使用 RSA 算法(兼容性更好)
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

# 参数说明:
# -t: 指定密钥类型(ed25519 或 rsa)
# -C: 添加注释(通常是邮箱)
# -b: 指定密钥长度(仅 RSA)

# 按提示操作:
# 1. 选择保存路径(默认 ~/.ssh/id_ed25519)
# 2. 设置密码短语(可留空,按回车跳过)
# 3. 确认密码短语

# 输出示例:
# Generating public/private ed25519 key pair.
# Enter file in which to save the key (~/.ssh/id_ed25519):
# Enter passphrase (empty for no passphrase):
# Enter same passphrase again:
# Your identification has been saved in ~/.ssh/id_ed25519
# Your public key has been saved in ~/.ssh/id_ed25519.pub

5.3 上传公钥到服务器

方法一:使用 ssh-copy-id(推荐)

bash
# 自动上传公钥到服务器
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@remote_host

# 示例
ssh-copy-id -i ~/.ssh/id_ed25519.pub root@192.168.31.77

# 输入服务器密码后,公钥自动添加到 ~/.ssh/authorized_keys

方法二:手动上传

bash
# 1. 查看本地公钥
cat ~/.ssh/id_ed25519.pub

# 输出示例:
# ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB... your_email@example.com

# 2. 登录远程服务器
ssh user@remote_host

# 3. 创建 .ssh 目录(如果不存在)
mkdir -p ~/.ssh
chmod 700 ~/.ssh

# 4. 添加公钥到 authorized_keys
echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB... your_email@example.com" >> ~/.ssh/authorized_keys

# 5. 设置权限
chmod 600 ~/.ssh/authorized_keys

# 6. 退出服务器
exit

5.4 配置 SSH Config

作用:简化 SSH 命令,无需记住 IP 和用户名。

bash
# 编辑 SSH 配置文件
vim ~/.ssh/config

# 或使用 VS Code 打开
code ~/.ssh/config

配置文件示例

bash
# ~/.ssh/config

# 服务器别名配置
Host ubuntu
    HostName 192.168.31.77        # 服务器 IP 或域名
    User root                     # 登录用户
    Port 22                       # SSH 端口
    IdentityFile ~/.ssh/id_ed25519 # 私钥路径

# 多服务器配置示例
Host production
    HostName 123.45.67.89
    User deploy
    Port 22
    IdentityFile ~/.ssh/id_rsa_production

Host staging
    HostName staging.example.com
    User ubuntu
    Port 2222
    IdentityFile ~/.ssh/id_rsa_staging

# 通配符配置
Host *
    AddKeysToAgent yes
    UseKeychain yes               # macOS Keychain

使用 SSH Config 别名

bash
# 配置前
ssh root@192.168.31.77

# 配置后
ssh ubuntu

# rsync 也可以使用别名
rsync -avz --delete ./dist/ ubuntu:/var/www/project/

5.5 测试 SSH 连接

bash
# 测试连接
ssh ubuntu

# 测试命令执行
ssh ubuntu "ls -la /var/www"

# 查看连接详情(调试模式)
ssh -v ubuntu

# 预期输出:
# Last login: Mon Jan 1 12:00:00 2024 from 192.168.31.100
# root@server:~#

5.6 排查 SSH 连接问题

bash
# 1. 检查 SSH 服务是否运行
ssh ubuntu "systemctl status sshd"

# 2. 检查防火墙
ssh ubuntu "ufw status"

# 3. 查看 SSH 日志
ssh ubuntu "tail -f /var/log/auth.log"

# 4. 测试密钥权限
ls -la ~/.ssh/
# 预期输出:
# id_ed25519      -rw------- (600)
# id_ed25519.pub  -rw-r--r-- (644)
# config          -rw------- (600)

# 5. 修复权限
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
chmod 600 ~/.ssh/config

六、完整实战案例

6.1 需求描述

实现一个 Vue3 项目的自动化部署:

  1. Git commit 时自动构建
  2. 自动上传到远程服务器
  3. 无需手动操作
  4. 支持 SSH 免密登录

6.2 完整配置

项目结构

code
my-project/
├── .husky/
│   └── pre-commit           # Git Hook
├── dist/                    # 构建产物(.gitignore)
├── src/                     # 源代码
├── deploy.sh                # 部署脚本
├── package.json
└── .gitignore

package.json

json
{
  "name": "my-project",
  "version": "1.0.0",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview",
    "prepare": "husky install"
  },
  "devDependencies": {
    "husky": "^8.0.0",
    "vite": "^4.0.0"
  }
}

deploy.sh

bash
#!/bin/bash

# 配置
REMOTE_HOST="ubuntu"
REMOTE_PATH="/var/www/my-project"
BUILD_DIR="./dist"

# 颜色
GREEN='\033[0;32m'
BLUE='\033[0;34m'
NC='\033[0m'

echo -e "${BLUE} 开始构建...${NC}"
npm run build

if [ $? -ne 0 ]; then
  echo "构建失败!"
  exit 1
fi

echo -e "${GREEN} 构建完成${NC}"
echo -e "${BLUE} 开始上传...${NC}"

rsync -avz --delete ${BUILD_DIR}/ ${REMOTE_HOST}:${REMOTE_PATH}/

if [ $? -ne 0 ]; then
  echo "上传失败!"
  exit 1
fi

echo -e "${GREEN} 部署完成!${NC}"

.husky/pre-commit

bash
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

./deploy.sh

.gitignore

gitignore
node_modules
dist
.env
.DS_Store

6.3 部署流程演示

bash
# ==================== 第一步:配置 SSH 免密登录 ====================
# 生成密钥(如果还没有)
ssh-keygen -t ed25519 -C "your_email@example.com"

# 上传公钥
ssh-copy-id -i ~/.ssh/id_ed25519.pub root@192.168.31.77

# 配置 SSH Config
echo "Host ubuntu
  HostName 192.168.31.77
  User root
  Port 22
  IdentityFile ~/.ssh/id_ed25519" >> ~/.ssh/config

# 测试连接
ssh ubuntu "echo '连接成功'"

# ==================== 第二步:安装依赖 ====================
pnpm install

# ==================== 第三步:初始化 Git 和 Husky ====================
git init
npx husky install

# 创建 pre-commit hook
npx husky add .husky/pre-commit "./deploy.sh"

# 赋予脚本执行权限
chmod +x deploy.sh
chmod +x .husky/pre-commit

# ==================== 第四步:测试自动部署 ====================
# 修改代码
echo "<h1>Hello World</h1>" > src/index.html

# 提交代码(触发自动部署)
git add .
git commit -m "feat: update homepage"

# 输出示例:
#  开始构建...
#  构建完成
#  开始上传...
# sending incremental file list
# index.html
# sent 1.23K bytes  received 38 bytes  2.54K bytes/sec
# total size is 5.67K  speedup is 2.23
#  部署完成!
# [main abc1234] feat: update homepage
#  1 file changed, 1 insertion(+)

# ==================== 第五步:验证部署 ====================
# 打开浏览器访问
# http://192.168.31.77

# 或使用 curl 测试
curl http://192.168.31.77

七、常见问题与解决方案

7.1 问题排查流程

code
自动化部署问题排查:
│
├── 1. rsync 命令不存在
│   ├── macOS: brew install rsync
│   ├── Ubuntu: apt install rsync
│   └── CentOS: yum install rsync
│
├── 2. SSH 连接失败
│   ├── 检查 SSH 服务:systemctl status sshd
│   ├── 检查防火墙:ufw status
│   ├── 检查密钥权限:chmod 600 ~/.ssh/id_ed25519
│   └── 查看 SSH 日志:tail -f /var/log/auth.log
│
├── 3. rsync 需要输入密码
│   ├── 公钥未上传到服务器
│   ├── authorized_keys 权限错误
│   └── SSH Config 配置错误
│
├── 4. Git Hooks 不执行
│   ├── Husky 未正确安装
│   ├── pre-commit 无执行权限
│   └── .husky 目录不存在
│
└── 5. 脚本执行失败
    ├── 查看错误输出
    ├── 手动执行脚本调试
    └── 检查路径和权限

7.2 常见错误汇总

错误信息原因分析解决方案
rsync: command not foundrsync 未安装brew install rsync (macOS)
Permission denied (publickey)SSH 密钥认证失败检查公钥是否上传到服务器
rsync: failed to connect网络不通或端口错误检查防火墙和 SSH 端口
script not executable脚本无执行权限chmod +x deploy.sh
.husky/pre-commit: No such fileHusky 未初始化npx husky install
npm: command not found环境变量问题使用绝对路径或配置 PATH

7.3 调试技巧

bash
# 1. 手动执行脚本(查看详细输出)
./deploy.sh

# 2. 测试 rsync 连接
rsync -avz --dry-run ./dist/ ubuntu:/tmp/test/

# 3. 测试 SSH 连接
ssh -v ubuntu

# 4. 查看 Git Hooks 日志
git commit --no-verify -m "test"  # 跳过 hooks

# 5. 调试 Shell 脚本
bash -x deploy.sh  # 显示每条执行的命令

八、进阶应用

8.1 多环境部署

bash
#!/bin/bash

# 根据分支选择部署环境
current_branch=$(git symbolic-ref --short HEAD)

if [ "$current_branch" = "main" ]; then
  REMOTE_HOST="production"
  REMOTE_PATH="/var/www/production"
elif [ "$current_branch" = "staging" ]; then
  REMOTE_HOST="staging"
  REMOTE_PATH="/var/www/staging"
else
  echo "当前分支:$current_branch,跳过部署"
  exit 0
fi

# 执行部署
npm run build
rsync -avz --delete ./dist/ ${REMOTE_HOST}:${REMOTE_PATH}/

8.2 部署后执行远程命令

bash
#!/bin/bash

# ... 部署代码 ...

# 重启服务
ssh ubuntu << 'EOF'
  # 重启 Nginx
  sudo systemctl restart nginx

  # 清理缓存
  rm -rf /var/www/project/cache/*

  # 设置权限
  chown -R www-data:www-data /var/www/project

  # 发送通知
  curl -X POST "https://api.slack.com/webhook" \
    -d '{"text":"部署完成"}'
EOF

8.3 部署回滚

bash
#!/bin/bash

# 备份当前版本
BACKUP_DIR="/var/www/backups/$(date +%Y%m%d_%H%M%S)"

ssh ubuntu << EOF
  mkdir -p ${BACKUP_DIR}
  cp -r /var/www/project ${BACKUP_DIR}/
EOF

# 部署新版本
npm run build
rsync -avz --delete ./dist/ ubuntu:/var/www/project/

# 如果失败,回滚
if [ $? -ne 0 ]; then
  echo "部署失败,开始回滚..."
  ssh ubuntu "cp -r ${BACKUP_DIR}/project/* /var/www/project/"
fi

8.4 部署通知

bash
#!/bin/bash

# 部署成功后发送通知
deploy_success() {
  # 企业微信机器人
  curl -X POST "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx" \
    -H 'Content-Type: application/json' \
    -d '{
      "msgtype": "text",
      "text": {
        "content": " 部署成功\n项目: my-project\n时间: '"$(date '+%Y-%m-%d %H:%M:%S')"'"
      }
    }'
}

# 部署失败通知
deploy_failed() {
  curl -X POST "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx" \
    -H 'Content-Type: application/json' \
    -d '{
      "msgtype": "text",
      "text": {
        "content": " 部署失败\n项目: my-project\n时间: '"$(date '+%Y-%m-%d %H:%M:%S')"'"
      }
    }'
}

# 主流程
if ./deploy.sh; then
  deploy_success
else
  deploy_failed
  exit 1
fi

九、学习要点总结

核心要点

  1. rsync 是高效的文件同步工具

    • 增量同步,只传输变化文件
    • 支持压缩传输(-z)
    • 支持删除目标多余文件(--delete)
    • 支持排除文件(--exclude)
  2. Husky 简化 Git Hooks 管理

    • 配置文件纳入版本控制
    • 团队共享配置
    • 自动初始化(npm prepare)
    • 跨平台支持
  3. SSH 免密登录是自动化基础

    • 密钥认证比密码更安全
    • 一次配置永久使用
    • SSH Config 简化连接
    • 脚本自动执行
  4. deploy.sh 是核心部署脚本

    • 构建项目
    • 同步文件
    • 执行远程命令
    • 错误处理
  5. 个人开发者的高效方案

    • 无需 CI/CD 服务
    • 代码不外泄
    • 快速迭代部署
    • 低成本高效

十、延伸学习资源

官方文档

进阶主题

code
推荐学习路径:
│
├── 1. CI/CD 集成
│   ├── GitHub Actions
│   ├── GitLab CI
│   └── 自动化测试
│
├── 2. 容器化部署
│   ├── Docker + rsync
│   ├── Docker Compose
│   └── 自动重启服务
│
├── 3. 监控告警
│   ├── 部署状态监控
│   ├── 自动回滚
│   └── 告警通知
│
├── 4. 多环境管理
│   ├── 开发/测试/生产
│   ├── 环境变量管理
│   └── 配置分离
│
└── 5. 安全加固
    ├── SSH 加固
    ├── 防火墙配置
    └── 密钥轮换

实践建议

  1. 从简单开始:先实现基础同步,再添加自动化
  2. 测试环境:先在测试服务器验证,再部署生产
  3. 备份策略:部署前备份,失败可回滚
  4. 日志记录:记录每次部署的时间和结果
  5. 错误处理:脚本中添加错误判断和退出

附录:命令速查表

rsync 命令

bash
# 本地同步
rsync -av /source/ /dest/

# 上传到服务器
rsync -avz -e ssh /local/ user@remote:/remote/

# 使用 SSH Config 别名
rsync -avz --delete ./dist/ ubuntu:/var/www/project/

# 排除文件
rsync -avz --exclude '.git' ./project/ user@remote:/path/

# 干运行(测试)
rsync -avz --dry-run ./dist/ user@remote:/path/

Husky 命令

bash
# 安装
pnpm add -D husky

# 初始化
npx husky install

# 创建 hook
npx husky add .husky/pre-commit "npm test"

# 手动执行 hook
.husky/pre-commit

SSH 命令

bash
# 生成密钥
ssh-keygen -t ed25519 -C "email@example.com"

# 上传公钥
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@host

# 测试连接
ssh user@host

# 执行远程命令
ssh user@host "ls -la"

# 使用别名
ssh ubuntu

Git Hooks 命令

bash
# 跳过 hooks
git commit --no-verify -m "message"

# 查看当前分支
git symbolic-ref --short HEAD

# 获取项目根目录
git rev-parse --show-toplevel

下一步学习:GitHub Actions 自动化部署、Docker 容器化自动化、多环境部署策略、监控告警系统集成。