初始提交:时之刃的小站

基于 VermilionVoid(朱墨留白)主题的个人博客。
- 站点配置集中在 src/data/site.ts 与 src/data/profile.ts
- 30 篇文章、8 条偶得、相册
- 评论使用自托管 twikoo
- 部署走 deploy.sh(rsync 到树莓派 + 云服务器)
This commit is contained in:
dsh
2026-09-14 20:44:12 +08:00
commit 6f4cc13a20
209 changed files with 36176 additions and 0 deletions
Executable
+132
View File
@@ -0,0 +1,132 @@
#!/bin/bash
# deploy.sh — 一键部署到树莓派 + 云服务器
#
# 用法:
# ./deploy.sh 构建并部署到两个目标(生产环境会先确认)
# ./deploy.sh -y 跳过确认
# ./deploy.sh --pi-only 只部署树莓派(内网预览)
# ./deploy.sh --cloud-only 只部署云服务器
# ./deploy.sh --skip-build 不重新构建,直接推送现有 dist/
# ./deploy.sh --dry-run 只显示 rsync 会做什么,不实际写入
set -euo pipefail
# ========== 配置区(按需修改) ==========
PI_HOST="192.168.1.87" # 树莓派 IP
PI_USER="pi"
PI_SITE_PATH="/home/pi/www/Astro_vermilion/" # 与 Firefly 分开放,方便对比
CLOUD_HOST="81.70.45.191" # 云服务器 IP
CLOUD_USER="root"
CLOUD_KEY="$HOME/.ssh/Astro.pem" # 云服务器 SSH 密钥
CLOUD_SITE_PATH="/opt/1panel/apps/caddy/caddy/data/srv/astro-blog/" # Caddy 站点目录
CLOUD_URL="http://81.70.45.191:3500"
# ========================================
cd "$(dirname "$0")"
DO_PI=1
DO_CLOUD=1
SKIP_BUILD=0
DRY_RUN=0
ASSUME_YES=0
for arg in "$@"; do
case "$arg" in
--pi-only) DO_CLOUD=0 ;;
--cloud-only) DO_PI=0 ;;
--skip-build) SKIP_BUILD=1 ;;
--dry-run) DRY_RUN=1 ;;
-y|--yes) ASSUME_YES=1 ;;
-h|--help)
sed -n '2,10p' "$0" | sed 's/^# \{0,1\}//'
exit 0
;;
*) echo "⚠️ 忽略未知参数: $arg" ;;
esac
done
if [ "$DO_PI" -eq 0 ] && [ "$DO_CLOUD" -eq 0 ]; then
echo "❌ 两个目标都被关掉了,无事可做"
exit 1
fi
# ---------- 1. 构建 ----------
if [ "$SKIP_BUILD" -eq 0 ]; then
echo "🔨 构建中..."
# 关键:构建失败必须中止。否则会拿着残缺或过期的 dist/ 执行 rsync --delete,
# 把线上站点删空。
if ! pnpm build; then
echo ""
echo "❌ 构建失败,已中止部署(没有推送任何内容)"
exit 1
fi
else
echo "⏭ 跳过构建(--skip-build)"
fi
# ---------- 2. 产物自检 ----------
if [ ! -f dist/index.html ]; then
echo "❌ dist/index.html 不存在,构建产物异常,已中止"
echo " (rsync --delete 会用它清空线上目录,所以这里必须拦住)"
exit 1
fi
PAGES=$(find dist -name '*.html' | wc -l)
SIZE=$(du -sh dist | cut -f1)
echo "✅ 构建产物:$PAGES 个页面,共 $SIZE"
if [ "$PAGES" -lt 5 ]; then
echo "⚠️ 页面数只有 $PAGES,看起来不像一次正常构建。"
if [ "$ASSUME_YES" -eq 0 ]; then
read -r -p " 仍要继续吗?[y/N] " reply
case "$reply" in [yY]*) ;; *) echo "已取消"; exit 1 ;; esac
fi
fi
# ---------- 3. 生产环境确认 ----------
if [ "$DO_CLOUD" -eq 1 ] && [ "$DRY_RUN" -eq 0 ] && [ "$ASSUME_YES" -eq 0 ]; then
echo ""
echo "⚠️ 即将用 --delete 覆盖云服务器目录(这是你的线上站点):"
echo " $CLOUD_USER@$CLOUD_HOST:$CLOUD_SITE_PATH"
read -r -p " 确认部署?[y/N] " reply
case "$reply" in [yY]*) ;; *) echo "已取消"; exit 1 ;; esac
fi
RSYNC_FLAGS=(-avz --delete)
[ "$DRY_RUN" -eq 1 ] && RSYNC_FLAGS+=(--dry-run) && echo "🔍 dry-run:只显示将要同步的内容"
FAIL=0
# ---------- 4. 树莓派 ----------
if [ "$DO_PI" -eq 1 ]; then
echo ""
echo "📦 推送到树莓派 ($PI_USER@$PI_HOST)"
if rsync "${RSYNC_FLAGS[@]}" dist/ "$PI_USER@$PI_HOST:$PI_SITE_PATH"; then
echo "✅ 树莓派部署完成: http://$PI_HOST"
else
echo "❌ 树莓派部署失败"
FAIL=1
fi
fi
# ---------- 5. 云服务器 ----------
if [ "$DO_CLOUD" -eq 1 ]; then
echo ""
echo "📦 推送到云服务器 ($CLOUD_USER@$CLOUD_HOST)"
if rsync "${RSYNC_FLAGS[@]}" -e "ssh -i $CLOUD_KEY" \
dist/ "$CLOUD_USER@$CLOUD_HOST:$CLOUD_SITE_PATH"; then
echo "✅ 云服务器部署完成: $CLOUD_URL"
else
echo "❌ 云服务器部署失败"
FAIL=1
fi
fi
echo ""
if [ "$FAIL" -eq 0 ]; then
[ "$DRY_RUN" -eq 1 ] && echo "🔍 dry-run 结束,没有实际改动。" || echo "🎉 全部部署完成!"
else
echo "⚠️ 有目标部署失败,请检查上面的报错信息。"
exit 1
fi