使用 rsync 部署静态网站——从手动到自动化

使用 rsync 部署静态网站——从手动到自动化

作者: CaoZH
日期: 2024-12-15
本文为原创教程


部署静态网站有很多方式:FTP、scp、GitHub Actions、rsync……其中最经典、最可靠的方式莫过于 rsync

rsync 增量同步、断点续传、权限保留,是运维老手最常用的部署工具。本文将从头到尾教你用 rsync 部署静态网站。

一、rsync 是什么?

rsync(remote sync)是一个远程文件同步工具,它的核心优势是:

特性 说明
增量传输 只传输差异部分,不是全量
断点续传 传输中断后继续,不从头来
压缩传输 传输过程中压缩数据
权限保留 保留文件权限、所有者、时间戳
安全可靠 通过 SSH 加密传输

rsync vs 其他方案

方案 速度 增量 安全性 复杂度
FTP
scp
rsync
GitHub Actions

二、安装 rsync

1
2
3
4
5
6
# 几乎所有 Linux 发行版都已预装
rsync --version

# 如果没有
sudo apt install -y rsync # Ubuntu/Debian
sudo yum install -y rsync # CentOS

三、基本用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 基本语法
rsync [选项] 源路径 目标路径

# 本地同步
rsync -av source/ backup/
# -a:归档模式(保留权限、所有者等)
# -v:显示传输详情

# 本地到远程(推送)
rsync -avz ./public/ user@server:/var/www/html/
# -z:传输时压缩

# 远程到本地(拉取)
rsync -avz user@server:/var/www/html/ ./backup/

# 通过 SSH(推荐)
rsync -avz -e ssh ./dist/ user@server:/var/www/html/

# 指定 SSH 端口
rsync -avz -e "ssh -p 2222" ./dist/ user@server:/var/www/html/

四、实战:部署 Hexo 博客

这是我自己的博客部署方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/bin/bash
# deploy.sh — 一键部署脚本

BLOG_DIR="/home/hermes/blog-site"
REMOTE_USER="blog"
REMOTE_HOST="43.143.72.145"
REMOTE_PATH="::blog"
PASSWORD_FILE="/home/hermes/rsync.passwd"

echo "📦 构建博客..."
cd $BLOG_DIR
npx hexo generate

echo "🚀 部署到服务器..."
rsync -avz --delete \
--password-file=$PASSWORD_FILE \
$BLOG_DIR/public/ \
${REMOTE_USER}@${REMOTE_HOST}${REMOTE_PATH}

echo "✅ 部署完成!"

五、rsync daemon 模式

除了通过 SSH,rsync 还可以以 daemon(守护进程)模式运行,部署更高效。

服务端配置

1
2
# 服务器上创建配置文件
sudo vim /etc/rsyncd.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# /etc/rsyncd.conf
uid = www-data
gid = www-data
use chroot = yes
max connections = 10
pid file = /var/run/rsyncd.pid
log file = /var/log/rsync.log
timeout = 300

[blog] # 模块名称
path = /var/www/blog # 网站目录
comment = My Blog
read only = no
list = yes
auth users = blog # 允许的用户
secrets file = /etc/rsyncd.secrets # 密码文件
1
2
3
4
5
6
7
# 创建密码文件
echo "blog:yourpassword" | sudo tee /etc/rsyncd.secrets
sudo chmod 600 /etc/rsyncd.secrets

# 启动 rsync daemon
sudo systemctl start rsync
sudo systemctl enable rsync

客户端配置

1
2
3
4
5
6
7
8
9
# 本地创建密码文件
echo "yourpassword" > ~/rsync.passwd
chmod 600 ~/rsync.passwd

# 部署命令
rsync -avz --delete \
--password-file=~/rsync.passwd \
./public/ \
blog@server-ip::blog

六、自动化部署脚本

基础版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/bin/bash
# deploy.sh
set -e

SITE_DIR="dist"
REMOTE_USER="deploy"
REMOTE_HOST="your-server.com"
REMOTE_PATH="/var/www/my-site"
SSH_KEY="~/.ssh/deploy_key"

echo "🔨 构建项目..."
npm run build

echo "🚀 部署到 $REMOTE_HOST..."
rsync -avz --delete \
-e "ssh -i $SSH_KEY" \
$SITE_DIR/ \
$REMOTE_USER@$REMOTE_HOST:$REMOTE_PATH/

echo "✅ 部署完成!访问 https://$REMOTE_HOST"

带备份的版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/bin/bash
# deploy-with-backup.sh
set -e

SITE_DIR="dist"
REMOTE_USER="deploy"
REMOTE_HOST="your-server.com"
REMOTE_PATH="/var/www/my-site"
BACKUP_PATH="/var/www/backups/$(date +%Y%m%d_%H%M%S)"

echo "🔨 构建..."
npm run build

echo "📦 备份当前版本..."
ssh $REMOTE_USER@$REMOTE_HOST "cp -r $REMOTE_PATH $BACKUP_PATH"

echo "🚀 部署新版本..."
rsync -avz --delete $SITE_DIR/ $REMOTE_USER@$REMOTE_HOST:$REMOTE_PATH/

echo "✅ 完成"

# 如果需要回滚:
# ssh $REMOTE_USER@$REMOTE_HOST "cp -r $BACKUP_PATH/* $REMOTE_PATH/"

七、rsync 常用选项

1
2
3
4
5
6
7
8
9
10
11
12
13
# 最常用组合(归档 + 压缩 + 进度)
rsync -avzP source/ dest/
# a:归档模式
# v:显示详情
# z:压缩
# P:显示进度 + 断点续传

# 其他有用选项
rsync --delete # 删除目标端多余文件(保持完全一致)
rsync --exclude="*.log" # 排除匹配的文件
rsync --exclude-from="exclude.txt" # 从文件读取排除规则
rsync --dry-run # 模拟运行(不实际传输)
rsync --bwlimit=1000 # 限速 1000KB/s

八、结合 GitHub Actions 自动化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# .github/workflows/deploy.yml
name: Deploy via rsync

on:
push:
branches: [main]

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- run: npm ci && npm run build

- name: rsync deploy
uses: burnett01/rsync-deployments@7.0
with:
switches: -avz --delete
path: dist/
remote_path: /var/www/my-site
remote_host: ${{ secrets.DEPLOY_HOST }}
remote_user: ${{ secrets.DEPLOY_USER }}
remote_key: ${{ secrets.DEPLOY_KEY }}

九、排错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 测试连接
rsync -avz --dry-run source/ user@host:dest/

# 查看 rsync daemon 模块
rsync user@host::

# 查看特定模块路径
rsync user@host::module

# 测试 SSH 连接
ssh user@host

# 查看日志
ssh user@host "tail -f /var/log/rsync.log"

十、总结

rsync 是最可靠的文件同步工具之一:

场景 推荐方式
✅ 小项目手动部署 rsync -avz ./dist/ user@host:/path/
✅ 自动化部署 Shell 脚本
✅ 团队协作 GitHub Actions + rsync
✅ 多服务器 rsync daemon 模式

核心口诀: -avz --delete 一套参数走天下。


首发于 CaoZH 的笔记