初始化:Astro 站点 + Sveltia CMS 后台 + 部署配置

This commit is contained in:
2026-06-11 17:18:51 +08:00
commit 53092b52db
37 changed files with 7586 additions and 0 deletions

82
docs/CMS.md Normal file
View File

@@ -0,0 +1,82 @@
# 在线内容管理方案Gitea + Sveltia CMS
> 目标:让维护人员通过网页在线编辑博客/项目,富文本写作、上传图片、插入视频,
> 发布后自动构建上线。全部自托管,数据在自己服务器。
## 1. 方案概述
采用 **Gitea自托管 Git+ Sveltia CMS在线写作后台+ Gitea Actions自动部署**
- Sveltia CMS 是 Decap CMS原 Netlify CMS的现代继任者**原生支持 Gitea 后端**
通过 Gitea OAuth 登录鉴权,无需额外搭建鉴权中转服务。
- 内容仍以 Markdown 形式存放在 Gitea 仓库,结构化、可版本管理、可回滚。
- 站点保持静态,安全、运维轻。
## 2. 架构
```
维护人员浏览器
├─► https://shizhui.xyz/admin Sveltia CMS 后台(写作/上传/发布)
│ │ Gitea OAuth 登录
│ ▼
└─► https://git.shizhui.xyz 自托管 Gitea内容 .md + 代码仓库)
│ 提交触发 Gitea Actions
npm run build → /var/www/shizhui → Nginx → https://shizhui.xyz
```
## 3. 组件角色
| 组件 | 作用 | 访问地址 |
|------|------|----------|
| Astro 站点 | 内容展示(已完成) | shizhui.xyz |
| Gitea | 自托管 Git、内容存储、CIActions | git.shizhui.xyz |
| Sveltia CMS | 在线写作后台(静态页面,挂在站点 /admin | shizhui.xyz/admin |
| Gitea Actions Runner | 监听提交,自动构建并发布 | 服务器内部 |
| Nginx | 托管静态站 + 反向代理 Gitea | — |
## 4. 编辑能力
- **富文本 + Markdown 双模式**:标题、加粗、列表、链接、代码块、引用等。
- **图片**:拖拽上传,自动存入仓库 `public/` 或指定媒体目录。
- **视频**
- 推荐嵌入式B站 / YouTube文章中粘贴嵌入不占服务器带宽。
- 也可自托管:上传视频文件,用 HTML5 `<video>` 播放(需注意带宽/存储)。
- 视频渲染能力由 Astro 站点模板提供CMS 负责录入。
## 5. 落地步骤(待用户授权 SSH 后执行)
> 以下涉及服务器操作,按 `.kiro/steering/commands.md` 规则,需用户确认授权后执行。
### 阶段一:基础设施
1. 服务器初始化Nginx、防火墙`docs/DEPLOY.md`)。
2. 安装 Gitea二进制或 docker数据目录规划配置 `git.shizhui.xyz`
3. Nginx 反向代理 Gitea申请 HTTPS 证书(含 git 子域名)。
4. 创建管理员账号,建立本项目仓库,推送现有代码。
### 阶段二CI 自动部署
5. 安装并注册 Gitea Actions Runner。
6. 编写 workflow`push` 到主分支 → `npm ci && npm run build` → 发布到 `/var/www/shizhui`
### 阶段三:接入 CMS
7. 在站点加入 `/admin`Sveltia CMS 页面 + `config.yml`)。
8. 在 Gitea 注册 OAuth 应用,把 client_id 配到 CMS。
9. 配置内容模型collectionsblog、projects字段对齐现有 frontmatter。
10. 配置媒体上传目录、视频嵌入支持。
### 阶段四:验证
11. 登录 /admin → 新建测试文章 → 发布 → 确认自动构建并上线。
12. 移交维护文档(如何写文章、加项目、插图插视频)。
## 6. 待确认 / 前置条件
- [ ] 用户授权 SSH 连接服务器执行安装(提供临时密码或 SSH 密钥,勿用长期密码)
- [ ] 确认服务器配置(内存/CPU足以同时运行 Gitea + 构建
- [ ] 确认 git 子域名方案git.shizhui.xyz并添加 DNS 解析
- [ ] 是否需要多个维护账号 / 权限分级
## 7. 备注
- 当前阶段网站已可用,内容用 Markdown 文件维护CMS 为平滑叠加,不推翻现有结构。
- 凭据不写入仓库与文档。

128
docs/DEPLOY.md Normal file
View File

@@ -0,0 +1,128 @@
# 部署与运维记录
> 记录服务器环境、部署流程与上线状态。凭据不写入本文件。
## 服务器信息
- 系统Ubuntu 26全新
- 域名shizhui.xyz已解析可 ping 通)
- 登录:建议改用 SSH 密钥,关闭 root 密码登录(待办)
## 部署架构
```
本地构建 (npm run build) → 生成 dist/ 静态文件
→ rsync/scp 上传到服务器 /var/www/shizhui
→ Nginx 托管
→ Let's Encrypt 提供 HTTPS
```
采用"本地构建 + 上传 dist"的方式,服务器无需安装 Node最简单、最稳定。
## 一、服务器初始化(首次)
```bash
# 更新系统
apt update && apt upgrade -y
# 安装 Nginx 与 certbot
apt install -y nginx certbot python3-certbot-nginx
# 防火墙放行 HTTP/HTTPS/SSH
ufw allow OpenSSH
ufw allow 'Nginx Full'
ufw --force enable
# 站点目录
mkdir -p /var/www/shizhui
```
## 二、Nginx 配置
文件:`/etc/nginx/sites-available/shizhui`(仓库内见 `deploy/nginx-shizhui.conf`
```bash
ln -sf /etc/nginx/sites-available/shizhui /etc/nginx/sites-enabled/shizhui
rm -f /etc/nginx/sites-enabled/default
nginx -t && systemctl reload nginx
```
## 三、申请 HTTPS 证书
```bash
certbot --nginx -d shizhui.xyz -d www.shizhui.xyz
# 自动续期已由 certbot 的 systemd timer 处理,可验证:
certbot renew --dry-run
```
## 四、发布更新(每次内容/代码变更后)
本地执行(见 `deploy/deploy.sh`
```bash
npm run build
rsync -avz --delete dist/ root@shizhui.xyz:/var/www/shizhui/
```
## 五、上线检查清单
- [x] 服务器初始化完成swap 2G + Nginx 1.28 + certbot 4.0 + ufw 防火墙)
- [x] Nginx 配置就位并 reload
- [x] 首次上传 dist服务器本机 HTTP 200 正常)
- [x] 阿里云安全组放行 80之前规则未应用到实例已修复80/8080 探测 open
- [x] HTTP 公网访问正常http://shizhui.xyz → 200
- [x] 阿里云安全组放行 443
- [x] HTTPS 证书申请成功DNS-01 验证,含 shizhui.xyz/www/git到期 2026-09-09自动续期已配
- [x] HTTPS 配置启用(本机握手 200HTTP 跳转 HTTPS
- [ ] 浏览器访问 https://shizhui.xyz 正常(**需先完成 ICP 备案**,否则被劫持)
- [ ] 清理临时 8080 测试配置(备案上线后)
- [ ] 更换 root 密码 + 配置 SSH 密钥登录
- [ ] 备案完成后轮转阿里云 AccessKey
## 排障记录:公网端口不通
现象:服务器内部 nginx/ufw 全正常,本机 HTTP 200但公网探测 80 closed、
nginx 日志无任何外部请求。
排查用服务器调用第三方端口探测服务ports.yougetsignal.com从外部探测
并对比高位端口 8080。最终定位为**阿里云安全组规则未应用到实例**(实例绑定的
安全组与编辑的安全组不一致)。修正绑定后 80/8080 探测变为 openHTTP 恢复正常。
结论:与备案、与本地 VPN 均无关,是安全组绑定问题。
## 排障记录HTTPS 证书 HTTP 验证失败 (403 / 200空响应)
现象80/443 端口已放行静态文件外部访问完全正常probe 文件本机/公网/www
三种方式均 200 且内容正确),但 certbot 的 ACME HTTP-01 验证始终失败:
Let's Encrypt 访问 `/.well-known/acme-challenge/<token>` 返回 403 或 200 空响应。
排查:
- webroot 与 nginx 插件两种方式都试过,均失败。
- 手动放置同目录静态文件testfile/probe123本机、公网 IP、www Host
三种请求都正常返回 200 + 正确内容。
- certbot 写入的 challenge 文件路径与内容均正确(已边写边抓验证)。
- 域名解析 IP 与服务器真实公网 IP 一致,未走 CDN。
- 唯一失败的是「瞬时新建的 acme-challenge 路径」被外部访问时异常。
判断:阿里云网络入口对突发的 `/.well-known/acme-challenge/` 新路径存在安全
拦截(国内服务器常见),导致 HTTP-01 验证不可用。
### 真正根因:域名未备案(已确认)
通过外部代理对比确认:
- `http://shizhui.xyz/`(域名+80→ 返回阿里云劫持页
`<title>Non-compliance ICP Filing</title>`(未备案提示),我们的网站被拦截。
- `http://8.137.165.96:8080/`IP+非标端口)→ 正常返回站点。
阿里云对**未备案域名**经标准端口80/443的访问会劫持到备案提示页
这正是 HTTP-01 验证拿到 403/异常响应的真正原因。
影响与对策:
- **HTTPS 证书**HTTP 验证不可用,改用 **DNS-01 验证**(阿里云 DNS 插件,已安装
certbot-dns-aliyun 2.0.0)。
- **域名正式可用前必须完成 ICP 备案**。备案前域名走 80/443 一律被劫持。
- **测试访问地址**(备案完成前):`http://8.137.165.96:8080/`
解决方案:改用 **DNS-01 验证**签发证书,绕开 80 端口。
- 方案一(采用):阿里云 DNS 插件 + RAM 子账号 AccessKey只给 DNS 权限),
全自动签发与续期。

95
docs/PROJECT.md Normal file
View File

@@ -0,0 +1,95 @@
# ShiZhui 网站 项目文档
> 本文档记录项目的方案、技术选型、结构与运维信息,随项目推进持续更新。
## 1. 项目概述
- **域名**shizhui.xyz已可 ping 通)
- **定位**:展示型网站(作品集 / 产品展示),非运营、非社交
- **内容方向**:电子工程、软件工程、通信、机器人类产品
- **维护者背景**嵌入式工程师Web 经验较少,需求是"结构清晰、长期可增量维护"
## 2. 技术选型
| 项 | 选择 | 说明 |
|----|------|------|
| 站点类型 | 静态站点SSG | 无后端、无数据库,安全面小、易运维 |
| 框架 | Astro 5 | 语法接近 HTML组件化内容用 Markdown将来可按需加交互组件 |
| 内容 | Markdown / MDX | 博客与项目内容用 Markdown 编写,便于维护 |
| 样式 | 原生 CSSCSS 变量主题) | 工程/极简科技风,暗色调,无重型 UI 框架 |
| 语言 | 中文为主 | |
| 部署 | Nginx 托管静态文件 | Ubuntu 26 服务器 |
| HTTPS | Let's Encryptcertbot | 免费证书,自动续期 |
| 内容管理 | Gitea + Sveltia CMS | 自托管 Git + 在线写作后台,详见 `docs/CMS.md` |
### 设计风格
- 工程 / 极简科技风
- 暗色调为主
- 强调可读性与信息密度
## 3. 站点板块
- 首页Home简介 + 精选项目/文章入口
- 关于About个人/团队介绍、技能方向
- 项目 / 产品Projects硬件/软件/通信/机器人作品展示
- 技术博客Blog技术文章
- 联系方式Contact
## 4. 工程结构
```
shizhui_website/
├── docs/ # 项目文档(本目录)
│ ├── PROJECT.md # 项目总览(本文件)
│ └── DEPLOY.md # 部署与运维记录
├── public/ # 静态资源(直接拷贝,不经构建)
├── src/
│ ├── components/ # 复用组件
│ ├── layouts/ # 页面布局
│ ├── pages/ # 路由页面(文件即路由)
│ ├── content/ # Markdown 内容集合blog / projects
│ └── styles/ # 全局样式与主题变量
├── astro.config.mjs # Astro 配置
├── package.json
└── tsconfig.json
```
## 5. 内容维护方式(给非前端的你)
- **加一篇博客**:在 `src/content/blog/` 新建一个 `.md` 文件,填好顶部 frontmatter标题、日期、摘要写正文即可。
- **加一个项目**:在 `src/content/projects/` 新建一个 `.md` 文件,填好 frontmatter名称、分类、简介、链接写详情即可。
- 改完后本地 `npm run build`,再部署。
## 6. 常用命令
```bash
npm install # 安装依赖
npm run dev # 本地开发预览(默认 http://localhost:4321
npm run build # 构建到 dist/
npm run preview # 预览构建结果
```
## 7. 待办 / 路线图
- [x] 技术选型与方案确定
- [x] 工程骨架搭建
- [x] 首页 / 关于 / 项目 / 博客 / 联系页面
- [x] 暗色主题样式
- [x] 本地构建验证(`npm run build` 通过8 页生成)
- [x] 在线内容管理方案确定Gitea + Sveltia CMS`docs/CMS.md`
- [ ] 服务器环境部署Nginx + HTTPS
- [ ] 自托管 Gitea + Sveltia CMS 在线编辑后台
- [ ] 域名解析与上线
### 已实现功能
- 响应式暗色主题CSS 变量,工程/极简科技风)
- 内容集合:`blog`(博客)+ `projects`(项目),均用 Markdown + frontmatter
- 项目页支持按分类(硬件/软件/通信/机器人)前端筛选
- 博客 RSS 订阅(`/rss.xml`、站点地图sitemap、SEO 与 OG 标签
- 站点信息集中在 `src/site.config.ts`(标题、导航、社交链接、邮箱)
## 8. 安全备注
- **务必**尽快更换服务器 root 密码,并改用 SSH 密钥登录、关闭密码登录。
- 凭据不写入仓库与文档(本文件不记录任何密码)。
- 静态站点无后端,攻击面主要在服务器 SSH 与 Nginx 配置。