diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..513abcd --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,108 @@ +# AI 代理指南 + +本文档为 AI 代理提供项目上下文和操作指南。 + +## 项目概述 + +- **类型**:Astro 静态博客站点 +- **域名**:https://wuyouwulv.me +- **仓库**:voson/publish(Gitea) +- **部署**:Gitea Actions → SSH → Vultr 服务器 + +## 技术栈 + +- **框架**:Astro 5.x +- **语言**:TypeScript +- **样式**:全局 CSS +- **部署**:Gitea Actions + SSH 密码认证 + +## 目录结构 + +``` +publish/ +├── .gitea/workflows/deploy.yml # CI/CD 部署工作流 +├── deploy/ # 部署文档和配置示例 +├── public/ # 静态资源 +├── src/ +│ ├── components/ # Astro 组件 +│ ├── content/blog/ # 博客文章(Markdown) +│ ├── layouts/ # 页面布局 +│ ├── pages/ # 页面路由 +│ └── styles/ # 全局样式 +└── astro.config.mjs # Astro 配置 +``` + +## 服务器配置 + +| 项目 | 值 | +|------|-----| +| 服务器 IP | `45.32.105.53` | +| SSH 用户 | `root` | +| SSH 端口 | `22` | +| 部署路径 | `/var/www/publish` | +| Web 服务器 | Caddy | + +服务器配置文件位置:`/Users/voson/Library/Mobile Documents/com~apple~CloudDocs/refining/config.toml` + +## Gitea 配置 + +- **实例**:https://gitea.refining.dev +- **仓库**:voson/publish(注意:不是 refining/publish) +- **Token**:见 `config.toml` 中的 `[services.gitea]` + +### Actions 变量(vars) + +| 变量 | 说明 | +|------|------| +| `SITE_URL` | 站点 URL,必须包含 `https://` | +| `DEPLOY_SSH_HOST` | 服务器 IP | +| `DEPLOY_SSH_PORT` | SSH 端口 | +| `DEPLOY_SSH_USER` | SSH 用户名 | +| `DEPLOY_PATH` | 部署目录 | +| `WEBHOOK_URL` | 飞书通知 Webhook | + +### Actions 密钥(secrets) + +| 密钥 | 说明 | +|------|------| +| `DEPLOY_SSH_PASSWORD` | SSH 登录密码 | + +## 常见操作 + +### 查看构建日志 + +```bash +# 获取最近的运行 +curl -s -H "Authorization: token TOKEN" \ + "https://gitea.refining.dev/api/v1/repos/voson/publish/actions/runs?limit=1" | jq . + +# 获取 job 日志 +curl -s -H "Authorization: token TOKEN" \ + "https://gitea.refining.dev/api/v1/repos/voson/publish/actions/jobs/JOB_ID/logs" +``` + +### 设置仓库变量 + +```bash +curl -X POST -H "Authorization: token TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"data":"VALUE","value":"VALUE"}' \ + "https://gitea.refining.dev/api/v1/repos/voson/publish/actions/variables/VAR_NAME" +``` + +### 手动部署 + +```bash +cd /Users/voson/publish +npm run build +tar -C dist -czf - . | sshpass -p 'PASSWORD' ssh root@45.32.105.53 \ + "set -euo pipefail; tmp='/var/www/publish.tmp'; rm -rf \"\$tmp\"; mkdir -p \"\$tmp\"; tar -xzf - -C \"\$tmp\"; rm -rf '/var/www/publish'; mv \"\$tmp\" '/var/www/publish'" +``` + +## 注意事项 + +1. **仓库路径**:仓库是 `voson/publish`,不是 `refining/publish` +2. **SITE_URL**:必须包含 `https://` 前缀,否则 Astro 构建会报 "Invalid url" +3. **SSH 认证**:使用密码认证(sshpass),不是 SSH 密钥 +4. **Gitea Cache**:Gitea 不支持 `actions/cache@v4`,必须使用 `v3` +5. **变量 vs 密钥**:敏感信息(密码)用 secrets,其他用 vars diff --git a/README.md b/README.md deleted file mode 100644 index d20e864..0000000 --- a/README.md +++ /dev/null @@ -1,62 +0,0 @@ -# Astro Starter Kit: Blog - -```sh -npm create astro@latest -- --template blog -``` - -> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun! - -Features: - -- ✅ Minimal styling (make it your own!) -- ✅ 100/100 Lighthouse performance -- ✅ SEO-friendly with canonical URLs and OpenGraph data -- ✅ Sitemap support -- ✅ RSS Feed support -- ✅ Markdown & MDX support - -## 🚀 Project Structure - -Inside of your Astro project, you'll see the following folders and files: - -```text -├── public/ -├── src/ -│   ├── components/ -│   ├── content/ -│   ├── layouts/ -│   └── pages/ -├── astro.config.mjs -├── README.md -├── package.json -└── tsconfig.json -``` - -Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name. - -There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components. - -The `src/content/` directory contains "collections" of related Markdown and MDX documents. Use `getCollection()` to retrieve posts from `src/content/blog/`, and type-check your frontmatter using an optional schema. See [Astro's Content Collections docs](https://docs.astro.build/en/guides/content-collections/) to learn more. - -Any static assets, like images, can be placed in the `public/` directory. - -## 🧞 Commands - -All commands are run from the root of the project, from a terminal: - -| Command | Action | -| :------------------------ | :----------------------------------------------- | -| `npm install` | Installs dependencies | -| `npm run dev` | Starts local dev server at `localhost:4321` | -| `npm run build` | Build your production site to `./dist/` | -| `npm run preview` | Preview your build locally, before deploying | -| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` | -| `npm run astro -- --help` | Get help using the Astro CLI | - -## 👀 Want to learn more? - -Check out [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat). - -## Credit - -This theme is based off of the lovely [Bear Blog](https://github.com/HermanMartinus/bearblog/). diff --git a/deploy/README.md b/deploy/README.md index 72a03fc..793080f 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -1,26 +1,126 @@ -# Server deploy (static) +# 部署文档 -This repo builds an Astro static site into `dist/` and deploys it to a Linux server via rsync over SSH. +本项目使用 Astro 构建静态站点,通过 Gitea Actions 自动部署到 Linux 服务器。 -## One-time server setup +## 架构概览 -1. Create a deploy directory, e.g. `/var/www/publish`. -2. Configure your web server (Caddy or Nginx) to serve that directory. -3. Create an SSH key for CI and add its public key to the server. +``` +本地开发 → Git Push → Gitea Actions → 构建 → SSH 部署 → 服务器 + ↓ + 飞书通知 +``` -## Gitea Actions secrets (repo settings) +## 服务器信息 -- `SITE_URL` -- `PUBLIC_NEWSLETTER_ACTION` -- `PUBLIC_NEWSLETTER_EMAIL_FIELD` -- `PUBLIC_NEWSLETTER_TITLE` (optional) -- `PUBLIC_NEWSLETTER_DESCRIPTION` (optional) -- `DEPLOY_SSH_HOST` -- `DEPLOY_SSH_PORT` -- `DEPLOY_SSH_USER` -- `DEPLOY_PATH` -- `DEPLOY_SSH_KEY` (private key) +| 项目 | 值 | +|------|-----| +| IP | `45.32.105.53` | +| 用户名 | `root` | +| 部署路径 | `/var/www/publish` | +| Web 服务器 | Caddy | +| 站点域名 | `https://wuyouwulv.me` | -## Example Caddyfile +## 一次性服务器配置 -See `deploy/Caddyfile.example`. +1. 创建部署目录: + ```bash + mkdir -p /var/www/publish + ``` + +2. 配置 Caddy(参考 `Caddyfile.example`): + ```bash + sudo vim /etc/caddy/Caddyfile + sudo systemctl reload caddy + ``` + +3. 确保服务器已安装 `tar`(用于解压部署包) + +## Gitea Actions 配置 + +### 仓库变量(vars) + +在仓库设置 → Actions → Variables 中配置: + +| 变量名 | 值 | 说明 | +|--------|-----|------| +| `SITE_URL` | `https://wuyouwulv.me` | 站点 URL,用于 Astro 构建 | +| `DEPLOY_SSH_HOST` | `45.32.105.53` | 服务器 IP | +| `DEPLOY_SSH_PORT` | `22` | SSH 端口 | +| `DEPLOY_SSH_USER` | `root` | SSH 用户名 | +| `DEPLOY_PATH` | `/var/www/publish` | 部署目录 | +| `WEBHOOK_URL` | 飞书 Webhook URL | 部署通知(可选) | + +### 仓库密钥(secrets) + +在仓库设置 → Actions → Secrets 中配置: + +| 密钥名 | 说明 | +|--------|------| +| `DEPLOY_SSH_PASSWORD` | SSH 登录密码 | + +### 通过 API 配置变量 + +```bash +# 设置变量 +curl -X POST -H "Authorization: token YOUR_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"data":"VALUE","value":"VALUE"}' \ + "https://gitea.refining.dev/api/v1/repos/OWNER/REPO/actions/variables/VAR_NAME" + +# 设置密钥 +curl -X PUT -H "Authorization: token YOUR_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"data":"SECRET_VALUE"}' \ + "https://gitea.refining.dev/api/v1/repos/OWNER/REPO/actions/secrets/SECRET_NAME" +``` + +## 部署流程 + +1. **Checkout** - 检出代码 +2. **Setup Node** - 安装 Node.js 20 +3. **Cache npm** - 缓存 npm 依赖(使用 `actions/cache@v3`) +4. **Install** - `npm ci` 安装依赖 +5. **Build** - `npm run build` 构建站点 +6. **Install sshpass** - 安装 SSH 密码认证工具 +7. **Add known_hosts** - 添加服务器到已知主机 +8. **Deploy** - 通过 tar + SSH 部署到服务器 +9. **通知** - 发送飞书通知(成功/失败) + +## 手动部署 + +如需手动部署,可以在本地执行: + +```bash +# 构建 +npm run build + +# 部署(需要 sshpass) +tar -C dist -czf - . | \ + sshpass -p 'PASSWORD' ssh -p 22 root@45.32.105.53 \ + "set -euo pipefail; tmp='/var/www/publish.tmp'; rm -rf \"\$tmp\"; mkdir -p \"\$tmp\"; tar -xzf - -C \"\$tmp\"; rm -rf '/var/www/publish'; mv \"\$tmp\" '/var/www/publish'" +``` + +## Caddy 配置示例 + +参考 `Caddyfile.example` 文件。 + +## 故障排查 + +### 构建失败:Invalid url + +检查 `SITE_URL` 变量是否包含完整的 URL(包括 `https://` 前缀)。 + +### 部署失败:SSH 连接问题 + +1. 检查 `DEPLOY_SSH_PASSWORD` 密钥是否正确 +2. 检查服务器 IP 和端口是否正确 +3. 检查服务器是否允许密码登录 + +### 变量在 UI 中不显示 + +Gitea UI 可能有显示问题,可以通过 API 验证变量是否存在: + +```bash +curl -s -H "Authorization: token YOUR_TOKEN" \ + "https://gitea.refining.dev/api/v1/repos/OWNER/REPO/actions/variables" | jq . +```