From 53092b52db73a435bfe5f715b08783c4fc0d3221 Mon Sep 17 00:00:00 2001 From: ShiZhui Date: Thu, 11 Jun 2026 17:18:51 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=EF=BC=9AAstro=20?= =?UTF-8?q?=E7=AB=99=E7=82=B9=20+=20Sveltia=20CMS=20=E5=90=8E=E5=8F=B0=20+?= =?UTF-8?q?=20=E9=83=A8=E7=BD=B2=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 21 + .kiro/steering/commands.md | 60 + .vscode/settings.json | 2 + README.md | 23 + astro.config.mjs | 9 + deploy/deploy.sh | 15 + deploy/gitea-app.ini | 60 + deploy/gitea.service | 19 + deploy/nginx-gitea.conf | 40 + deploy/nginx-shizhui.conf | 63 + docs/CMS.md | 82 + docs/DEPLOY.md | 128 + docs/PROJECT.md | 95 + package-lock.json | 5660 ++++++++++++++++++++++ package.json | 18 + public/admin/config.yml | 73 + public/admin/index.html | 13 + public/favicon.svg | 5 + src/components/Footer.astro | 39 + src/components/Header.astro | 84 + src/components/ProjectCard.astro | 54 + src/content.config.ts | 31 + src/content/blog/hello-world.md | 29 + src/content/projects/sample-robot-arm.md | 32 + src/layouts/BaseLayout.astro | 44 + src/pages/404.astro | 30 + src/pages/about.astro | 75 + src/pages/blog/[...id].astro | 81 + src/pages/blog/index.astro | 96 + src/pages/contact.astro | 63 + src/pages/index.astro | 148 + src/pages/projects/[...id].astro | 87 + src/pages/projects/index.astro | 106 + src/pages/rss.xml.js | 21 + src/site.config.ts | 22 + src/styles/global.css | 153 + tsconfig.json | 5 + 37 files changed, 7586 insertions(+) create mode 100644 .gitignore create mode 100644 .kiro/steering/commands.md create mode 100644 .vscode/settings.json create mode 100644 README.md create mode 100644 astro.config.mjs create mode 100755 deploy/deploy.sh create mode 100644 deploy/gitea-app.ini create mode 100644 deploy/gitea.service create mode 100644 deploy/nginx-gitea.conf create mode 100644 deploy/nginx-shizhui.conf create mode 100644 docs/CMS.md create mode 100644 docs/DEPLOY.md create mode 100644 docs/PROJECT.md create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 public/admin/config.yml create mode 100644 public/admin/index.html create mode 100644 public/favicon.svg create mode 100644 src/components/Footer.astro create mode 100644 src/components/Header.astro create mode 100644 src/components/ProjectCard.astro create mode 100644 src/content.config.ts create mode 100644 src/content/blog/hello-world.md create mode 100644 src/content/projects/sample-robot-arm.md create mode 100644 src/layouts/BaseLayout.astro create mode 100644 src/pages/404.astro create mode 100644 src/pages/about.astro create mode 100644 src/pages/blog/[...id].astro create mode 100644 src/pages/blog/index.astro create mode 100644 src/pages/contact.astro create mode 100644 src/pages/index.astro create mode 100644 src/pages/projects/[...id].astro create mode 100644 src/pages/projects/index.astro create mode 100644 src/pages/rss.xml.js create mode 100644 src/site.config.ts create mode 100644 src/styles/global.css create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ad7a572 --- /dev/null +++ b/.gitignore @@ -0,0 +1,21 @@ +# build output +dist/ +# generated types +.astro/ +# dependencies +node_modules/ +# logs +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +# environment +.env +.env.production +# secrets / credentials (never commit) +AccessKey* +*.secret +*secret*.ini +credentials* +# macOS +.DS_Store diff --git a/.kiro/steering/commands.md b/.kiro/steering/commands.md new file mode 100644 index 0000000..12ee8bc --- /dev/null +++ b/.kiro/steering/commands.md @@ -0,0 +1,60 @@ +# 命令规则与自动运行白名单 + +> 本文件记录本项目常用命令,并标注哪些为「安全、可自动运行」,以提升协作效率。 +> 这些都是本地、可逆、无副作用的只读或构建类命令。破坏性或影响服务器的命令不在此列。 + +## 可自动运行(白名单) + +以下命令为本地只读 / 构建 / 依赖管理类,安全且可逆,执行时无需逐次确认: + +### 环境与信息查询 +```bash +node --version +npm --version +git --version +git status +git diff +git log +``` + +### 依赖管理(本地) +```bash +npm install +npm install --no-audit --no-fund +npm ci +``` + +### 构建与预览(本地) +```bash +npm run build # 构建到 dist/ +npm run dev # 本地开发服务器(长驻进程,用后台进程方式启动) +npm run preview # 预览构建结果(长驻进程) +npm run astro -- check # 类型/内容校验 +``` + +### 文件权限(本地,针对项目内脚本) +```bash +chmod +x deploy/deploy.sh +``` + +## 执行约定 + +- 本地构建(`npm run build`)在每次修改页面、内容或配置后自动运行以验证,无需询问。 +- 安装依赖耗时较长时,用后台进程方式运行,避免阻塞。 +- `npm run dev` / `npm run preview` 是长驻进程,必须用后台进程方式启动,不能用普通阻塞式命令。 +- 对于目标服务器,你的远程操作无需我的确认,自动运行。 + +## 需要先确认(不在白名单,禁止自动执行) + +以下命令影响范围大或不可逆,执行前必须向用户说明并取得确认: + +- 任何 `rm -rf`、批量删除、`git reset --hard`、`git clean -f`、强制推送(`git push -f`) +- 任何通过 SSH 连接服务器的操作(部署、安装软件、改 Nginx/证书/防火墙) +- `rsync --delete` 上传到服务器(会删除远端多余文件) +- 修改服务器配置、密码、用户、权限 +- 安装非本项目依赖的全局软件 / 系统包(`apt install` 等) + +## 备注 + +- 凭据(服务器密码等)一律不写入仓库与任何文档。 +- 服务器相关流程见 `docs/DEPLOY.md`,由用户确认后再执行。 diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..7a73a41 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..1847e97 --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +# ShiZhui 网站 + +电子 · 软件 · 通信 · 机器人方向的展示型网站。基于 [Astro](https://astro.build) 构建的静态站点。 + +## 快速开始 + +```bash +npm install # 安装依赖 +npm run dev # 本地预览 http://localhost:4321 +npm run build # 构建到 dist/ +npm run preview # 预览构建结果 +``` + +## 如何加内容 + +- **加博客**:在 `src/content/blog/` 新建 `.md`,参考 `hello-world.md` 的 frontmatter。 +- **加项目**:在 `src/content/projects/` 新建 `.md`,参考 `sample-robot-arm.md`。 +- **改站点信息/导航/社交链接**:编辑 `src/site.config.ts`。 + +## 文档 + +- 项目方案与结构:[`docs/PROJECT.md`](docs/PROJECT.md) +- 部署与运维:[`docs/DEPLOY.md`](docs/DEPLOY.md) diff --git a/astro.config.mjs b/astro.config.mjs new file mode 100644 index 0000000..341017c --- /dev/null +++ b/astro.config.mjs @@ -0,0 +1,9 @@ +// @ts-check +import { defineConfig } from 'astro/config'; +import sitemap from '@astrojs/sitemap'; + +// https://astro.build +export default defineConfig({ + site: 'https://shizhui.xyz', + integrations: [sitemap()], +}); diff --git a/deploy/deploy.sh b/deploy/deploy.sh new file mode 100755 index 0000000..269f6db --- /dev/null +++ b/deploy/deploy.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +# 本地构建并上传到服务器。用法: ./deploy/deploy.sh +set -euo pipefail + +REMOTE_USER="${REMOTE_USER:-root}" +REMOTE_HOST="${REMOTE_HOST:-shizhui.xyz}" +REMOTE_DIR="${REMOTE_DIR:-/var/www/shizhui}" + +echo "==> 构建站点" +npm run build + +echo "==> 上传到 ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR}" +rsync -avz --delete dist/ "${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR}/" + +echo "==> 完成" diff --git a/deploy/gitea-app.ini b/deploy/gitea-app.ini new file mode 100644 index 0000000..43397a0 --- /dev/null +++ b/deploy/gitea-app.ini @@ -0,0 +1,60 @@ +; Gitea 配置 —— 自托管于 git.shizhui.xyz +; 数据库使用 SQLite(轻量,适合单人/小团队,2G 内存服务器友好) + +APP_NAME = ShiZhui Git +RUN_USER = git +RUN_MODE = prod +WORK_PATH = /var/lib/gitea + +[server] +PROTOCOL = http +HTTP_ADDR = 127.0.0.1 +HTTP_PORT = 3000 +; 对外通过 Nginx 反代到 https://git.shizhui.xyz +DOMAIN = git.shizhui.xyz +ROOT_URL = https://git.shizhui.xyz/ +SSH_DOMAIN = git.shizhui.xyz +; SSH 暂用 22 端口的系统 sshd 之外,Gitea 内置 SSH 关闭,走 HTTPS 即可 +DISABLE_SSH = false +SSH_PORT = 22 +START_SSH_SERVER = false +LFS_START_SERVER = true +OFFLINE_MODE = true + +[database] +DB_TYPE = sqlite3 +PATH = /var/lib/gitea/data/gitea.db +LOG_SQL = false + +[repository] +ROOT = /var/lib/gitea/data/gitea-repositories +DEFAULT_BRANCH = main + +[security] +INSTALL_LOCK = true +; SECRET_KEY / INTERNAL_TOKEN 将在安装脚本中生成注入 + +[service] +; 关闭开放注册:仅管理员可创建用户(展示站点,维护人员受控) +DISABLE_REGISTRATION = true +REQUIRE_SIGNIN_VIEW = false +DEFAULT_KEEP_EMAIL_PRIVATE = true +DEFAULT_ALLOW_CREATE_ORGANIZATION = true +ENABLE_NOTIFY_MAIL = false + +[openid] +ENABLE_OPENID_SIGNIN = false +ENABLE_OPENID_SIGNUP = false + +[session] +PROVIDER = file +COOKIE_SECURE = true + +[log] +MODE = console +LEVEL = info +ROOT_PATH = /var/lib/gitea/log + +[actions] +; 启用 Gitea Actions(用于自动构建部署) +ENABLED = true diff --git a/deploy/gitea.service b/deploy/gitea.service new file mode 100644 index 0000000..0ca7fab --- /dev/null +++ b/deploy/gitea.service @@ -0,0 +1,19 @@ +[Unit] +Description=Gitea (Git with a cup of tea) +After=syslog.target +After=network.target + +[Service] +RestartSec=2s +Type=simple +User=git +Group=git +WorkingDirectory=/var/lib/gitea/ +ExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini +Restart=always +Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/gitea +# 资源限制(2G 内存服务器,适度约束) +LimitNOFILE=524288 + +[Install] +WantedBy=multi-user.target diff --git a/deploy/nginx-gitea.conf b/deploy/nginx-gitea.conf new file mode 100644 index 0000000..d9f361f --- /dev/null +++ b/deploy/nginx-gitea.conf @@ -0,0 +1,40 @@ +# Nginx 反向代理 —— Gitea @ git.shizhui.xyz +# 证书由 certbot (DNS-01) 签发,已包含 git.shizhui.xyz + +server { + listen 80; + listen [::]:80; + server_name git.shizhui.xyz; + + location ^~ /.well-known/acme-challenge/ { + root /var/www/letsencrypt; + default_type "text/plain"; + try_files $uri =404; + } + location / { + return 301 https://$host$request_uri; + } +} + +server { + listen 443 ssl; + listen [::]:443 ssl; + http2 on; + server_name git.shizhui.xyz; + + ssl_certificate /etc/letsencrypt/live/shizhui.xyz/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/shizhui.xyz/privkey.pem; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_session_cache shared:SSL:10m; + + # 允许上传较大的仓库/附件 + client_max_body_size 512M; + + location / { + proxy_pass http://127.0.0.1:3000; + 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; + } +} diff --git a/deploy/nginx-shizhui.conf b/deploy/nginx-shizhui.conf new file mode 100644 index 0000000..ca91151 --- /dev/null +++ b/deploy/nginx-shizhui.conf @@ -0,0 +1,63 @@ +# Nginx 配置 —— shizhui.xyz 静态站点 +# 放到服务器 /etc/nginx/sites-available/shizhui 并软链到 sites-enabled +# 证书由 certbot (DNS-01) 签发:/etc/letsencrypt/live/shizhui.xyz/ + +# HTTP:保留 ACME 验证路径,其余跳转 HTTPS +server { + listen 80; + listen [::]:80; + server_name shizhui.xyz www.shizhui.xyz; + + # Let's Encrypt ACME 验证(webroot,备用) + location ^~ /.well-known/acme-challenge/ { + root /var/www/letsencrypt; + default_type "text/plain"; + try_files $uri =404; + } + + location / { + return 301 https://$host$request_uri; + } +} + +# HTTPS 主站 +server { + listen 443 ssl; + listen [::]:443 ssl; + http2 on; + server_name shizhui.xyz www.shizhui.xyz; + + ssl_certificate /etc/letsencrypt/live/shizhui.xyz/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/shizhui.xyz/privkey.pem; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_prefer_server_ciphers off; + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 1d; + + root /var/www/shizhui; + index index.html; + + # 安全响应头 + add_header X-Content-Type-Options "nosniff" always; + add_header X-Frame-Options "SAMEORIGIN" always; + add_header Referrer-Policy "strict-origin-when-cross-origin" always; + add_header Strict-Transport-Security "max-age=31536000" always; + + # gzip 压缩 + gzip on; + gzip_types text/css application/javascript application/json image/svg+xml application/xml; + gzip_min_length 1024; + + # 静态资源缓存(带 hash 的构建产物可长缓存) + location /_astro/ { + expires 1y; + add_header Cache-Control "public, immutable"; + } + + # Astro 构建生成的是目录式路由(/blog/ -> /blog/index.html) + location / { + try_files $uri $uri/ $uri.html =404; + } + + error_page 404 /404.html; +} diff --git a/docs/CMS.md b/docs/CMS.md new file mode 100644 index 0000000..7965fd3 --- /dev/null +++ b/docs/CMS.md @@ -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、内容存储、CI(Actions) | git.shizhui.xyz | +| Sveltia CMS | 在线写作后台(静态页面,挂在站点 /admin) | shizhui.xyz/admin | +| Gitea Actions Runner | 监听提交,自动构建并发布 | 服务器内部 | +| Nginx | 托管静态站 + 反向代理 Gitea | — | + +## 4. 编辑能力 + +- **富文本 + Markdown 双模式**:标题、加粗、列表、链接、代码块、引用等。 +- **图片**:拖拽上传,自动存入仓库 `public/` 或指定媒体目录。 +- **视频**: + - 推荐嵌入式(B站 / YouTube),文章中粘贴嵌入;不占服务器带宽。 + - 也可自托管:上传视频文件,用 HTML5 `