准备工作
1.1 服务器环境与依赖安装
在开始之前,确保服务器已安装必要的基础工具:
sudo apt update
sudo apt install -y git curl rsync
- git:拉取博客代码。
- rsync:高效同步
dist目录到网站根目录。 - curl:用于后续安装 Node.js。
1.2 安装 Node.js 与 pnpm
Astro 博客需要 Node.js 环境,推荐安装 LTS 版本(如 22.x):
# 添加 NodeSource 仓库
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
# 安装 Node.js(包含 npm)
sudo apt install -y nodejs
# 验证版本
node -v
npm -v
接下来安装 pnpm 作为包管理器,它安装更快且依赖管理更严格。推荐使用 Node.js 内置的 corepack 启用:
# 启用 corepack
corepack enable
# 准备最新 pnpm
corepack prepare pnpm@latest --activate
# 验证
pnpm -v
也可以使用
npm install -g pnpm,但可能需要sudo权限。corepack方式无需 root 即可全局使用。
1.3 私有仓库的 SSH Deploy Key 配置
如果你的博客仓库是私有的,需要在服务器上配置 SSH 密钥,以便自动化脚本无密码拉取代码。
生成专用密钥(以 ubuntu 用户为例):
ssh-keygen -t ed25519 -C "astro-blog-deploy" -f ~/.ssh/astro_deploy_key
按提示直接回车,不要设置 passphrase,否则自动化脚本会卡住。
添加公钥到 GitHub:
cat ~/.ssh/astro_deploy_key.pub
复制输出内容,打开仓库的 Settings → Deploy keys → Add deploy key,粘贴公钥并勾选 Allow write access(只读即可,无需勾选)。
配置 SSH 客户端:
# 编辑 ~/.ssh/config(不存在则新建)
nano ~/.ssh/config
写入:
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/astro_deploy_key
IdentitiesOnly yes
预存主机指纹(避免首次连接询问):
ssh-keyscan github.com >> ~/.ssh/known_hosts
测试连接:
ssh -T git@github.com
看到 Hi <用户名>! 即成功。
克隆仓库(使用 SSH 地址):
git clone git@github.com:你的用户名/你的仓库名.git /var/www/my-astro-blog
编写部署脚本
2.1 创建 deploy.sh
将部署脚本放在 /home/ubuntu/deploy.sh,统一管理:
nano /home/ubuntu/deploy.sh
粘贴以下内容(使用 pnpm):
#!/bin/bash
# --- 配置区 ---
REPO_DIR="/var/www/my-astro-blog" # 项目路径
BRANCH="main" # 要拉取的分支
LOG_FILE="/home/ubuntu/astro-deploy.log" # 日志文件
# -------------
echo "=== 开始部署: $(date) ===" >> "$LOG_FILE"
cd "$REPO_DIR" || { echo "!! 无法进入目录 $REPO_DIR" >> "$LOG_FILE"; exit 1; }
echo ">> 拉取最新代码..." >> "$LOG_FILE"
git fetch origin >> "$LOG_FILE" 2>&1
git reset --hard "origin/$BRANCH" >> "$LOG_FILE" 2>&1
echo ">> 安装依赖(pnpm)..." >> "$LOG_FILE"
pnpm install --frozen-lockfile >> "$LOG_FILE" 2>&1
echo ">> 开始构建 Astro 站点..." >> "$LOG_FILE"
pnpm build >> "$LOG_FILE" 2>&1
if [ $? -eq 0 ]; then
echo ">> 构建成功,同步文件到 /var/www/html ..." >> "$LOG_FILE"
rsync -avz --delete "$REPO_DIR/dist/" /var/www/html/ >> "$LOG_FILE" 2>&1
echo "=== 部署成功: $(date) ===" >> "$LOG_FILE"
else
echo "!!! 构建失败,请检查日志 !!!" >> "$LOG_FILE"
exit 1
fi
赋予执行权限:
chmod +x /home/ubuntu/deploy.sh
2.2 脚本解析
整个脚本执行三个核心步骤:
- 拉取最新代码:
git fetch+git reset --hard确保本地仓库与远程完全一致,避免本地修改冲突。 - 安装依赖并构建:使用
pnpm install --frozen-lockfile严格按锁文件安装,保证环境一致性;pnpm build生成静态文件到dist目录。 - 同步到网站目录:
rsync --delete将dist内容完全覆盖到/var/www/html,删除多余文件。
注意:脚本运行用户需要有
/var/www/html的写入权限:sudo chown ubuntu:ubuntu /var/www/my-astro-blog sudo chown ubuntu:ubuntu /var/www/html
搭建 Webhook 监听服务
3.1 安装 webhook 工具
sudo apt install -y webhook
3.2 配置 hooks.json
创建配置文件目录(放在家目录方便管理):
mkdir -p /home/ubuntu/webhook
nano /home/ubuntu/webhook/hooks.json
写入:
[
{
"id": "deploy-blog",
"execute-command": "/home/ubuntu/deploy.sh",
"command-working-directory": "/home/ubuntu",
"response-message": "博客部署已触发。",
"trigger-rule": {
"and": [
{
"match": {
"type": "payload-hmac-sha256",
"secret": "你的随机秘密字符串",
"parameter": {
"source": "header",
"name": "X-Hub-Signature-256"
}
}
},
{
"match": {
"type": "value",
"value": "refs/heads/main",
"parameter": {
"source": "payload",
"name": "ref"
}
}
}
]
}
}
]
- secret:一个随机的长字符串,用于验证请求来自 GitHub(后面会用到)。
- trigger-rule:同时满足两个条件才触发:签名验证通过,且推送分支为
main。
3.3 创建 Systemd 服务并开机自启
sudo nano /etc/systemd/system/webhook.service
写入:
[Unit]
Description=Webhook Listener for Astro Blog
After=network.target
[Service]
ExecStart=/usr/bin/webhook -hooks /home/ubuntu/webhook/hooks.json -port 9000 -verbose
Restart=always
User=ubuntu
Group=ubuntu
Environment=PATH=/usr/bin:/usr/local/bin:/home/ubuntu/.local/bin
[Install]
WantedBy=multi-user.target
启动并设置自启:
sudo systemctl daemon-reload
sudo systemctl enable webhook.service
sudo systemctl start webhook.service
检查状态:
sudo systemctl status webhook.service
确保 Active: active (running)。
配置 Nginx 反向代理(可选)
4.1 为 Webhook 添加域名与 HTTPS
直接暴露 http://ip:9000 不安全,建议用 Nginx 反代并配上 SSL。在你的 Nginx 配置中添加一个 server 块:
server {
listen 127.0.0.1:8001 ssl http2 proxy_protocol;
set_real_ip_from 127.0.0.1;
real_ip_header proxy_protocol;
server_name webhook.yourdomain.com;
add_header Strict-Transport-Security "max-age=63072000" always;
location / {
proxy_pass http://127.0.0.1:9000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
- 这里假设你的前置代理(如 Xray)已经将流量转发到
127.0.0.1:8001并处理了 SSL。 - 修改后执行
sudo nginx -t && sudo systemctl reload nginx使配置生效。
4.2 反代的作用
- HTTPS 加密:保护 Webhook Secret 在传输中不被窃取。
- 端口统一:复用 443 端口,无需额外开放 9000 端口。
- 日志与安全:可结合 Nginx 做访问控制或日志记录。
在 GitHub 仓库中设置 Webhook
5.1 填写 Payload URL 与 Secret
进入你的博客仓库 Settings → Webhooks → Add webhook,填写:
- Payload URL:
https://webhook.yourdomain.com/hooks/deploy-blog(注意路径与hooks.json中的id一致)。 - Content type:选择
application/json。 - Secret:填入
hooks.json中设置的secret字符串。 - 事件:选择
Just the push event.
点击 Add webhook。
5.2 测试自动部署流程
- 在本地修改博客内容,推送到
main分支。 - 观察服务器日志:
或查看 webhook 服务日志:tail -f /home/ubuntu/astro-deploy.logsudo journalctl -u webhook.service -f - 几分钟后访问你的网站,确认内容已更新。
如果 GitHub 显示 “Last delivery was successful”,但网站没更新,请检查日志中是否有 Hook rules were not satisfied 的错误。这通常是因为 Secret 不一致或推送分支不是 main 导致的。
至此,你的 Astro 博客全自动部署流水线就搭建完成了。每次只需 git push,服务器就会自动拉取、构建、更新网站,省心又高效。
喜欢的话,留下你的评论吧~