catalog/repos/aatrooox--blog-zzao-club.md

283 lines
8.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Nuxt全栈博客站
`Nuxt` `博客` `全栈` `Vue` `MySQL` `Redis`
# 博客站
一个基于 [Nuxt@4.0.3](https://nuxt.com/)、[NuxtContent@3.4.0](https://content.nuxt.com/)、[shadcn/vue](https://www.shadcn-vue.com/)、[inspira-ui](https://inspira-ui.com/components)、Drizzle、MySQL、Redis 的全栈站点
**娱乐性质的个人空间!**
![](/githubAssets/page-home.png)
![](/githubAssets/page-memo.png)
![](/githubAssets/page-articles.png)
## 功能
- 登录注册(用户名+密码)
- GitHub 登录
- 点赞
- 评论
- MySQL
- Redis
- 一键复制 HTML 到公众号(保留所有样式)
- `$fetch/useFetch` 最佳实践
- Sitemap
- RSS
- robots.txt
- PAT 认证
## 安装依赖
`git clone` 克隆或下载本仓库到本地
`.nvmrc``.node-version` 中标识了 Node 版本
安装:
```bash
npm i
pnpm i
```
视报错信息而定:
涉及从 npm 切换到 pnpm 时,可能需要重新 `pnpm add better-sqlite3``pnpm rebuild better-sqlite3`
## 零环境快速开始(本地开发)
先决条件:
- Node.js 20+(建议用 nvm 管理PNPM 10+
- Docker 与 Docker Compose用于本地 MySQL/Redis
- macOS/Linux 或 Windows WSL2 环境
步骤:
1) 启动数据库与缓存(使用内置 compose
```bash
docker compose -f docker-compose.local.yml up -d
```
默认账号与端口:
- MySQL: root / 123456数据库 blog端口 3306
- Redis: 无密码,端口 6379
2) 创建 .env项目根目录
```bash
# 数据库连接(与 compose 保持一致)
DATABASE_URL=mysql://root:123456@127.0.0.1:3306/blog
# Redis不配置则默认 127.0.0.1:6379
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
# 从 GitHub 仓库拉取文章内容所需(如不使用,可留空或注释 content.config.ts 的 source
CONTENT_REPO_TOKEN=
# 应用密钥(本地可任意随机值,生产需妥善保管)
NUXT_SESSION_PASSWORD=please_set_a_32_chars_random_string
NUXT_JWT_SECRET=please_set_a_random_string
# 可选:邮件/COS 等第三方配置(本地可留空)
NUXT_NODEMAILER_HOST=
NUXT_NODEMAILER_PORT=
NUXT_NODEMAILER_AUTH_USER=
NUXT_NODEMAILER_AUTH_PASS=
NUXT_COS_SECRET_ID=
NUXT_COS_SECRET_KEY=
NUXT_COS_BUCKET=
NUXT_COS_REGION=
```
3) 初始化数据库(二选一)
优先使用迁移(如果仓库已包含 `lib/drizzle/migrations`
```bash
pnpm db:migrate
```
如果没有历史迁移或希望按 `schema.ts` 直接同步结构:
```bash
pnpm db:push
```
4) 启动开发服务器
```bash
pnpm dev
```
访问http://localhost:4775
排错小贴士:
- 3306/6379 端口被占用:修改 `docker-compose.local.yml` 的端口映射,或停止占用进程。
- better-sqlite3 报错:执行 `pnpm rebuild better-sqlite3`
- 无法拉取 GitHub 文章:确认 `CONTENT_REPO_TOKEN` 有权限,或临时注释 `content.config.ts``source` 配置。
## 运行前配置
`content.config.ts`
```ts
// content 可以随意更改,对应的是 queryCollection 的第一个参数
content: defineCollection({
// page 表示会一对一生成路由
type: 'page',
source: {
// 过滤 md 文件,因为一个 ob 库里可能什么文件都有
include: '**/*.md',
// 过滤掉某些文件,如没写完的或者不想给人看的
// book 是我的 ob 根目录下的一个文件夹名称,视情况修改
exclude: ['**/-*.md', 'book/**/*.md'],
// 路由前缀 /post因为渲染文章的 vue 文件位于 app/pages/post/[...slug].vue
// 所以为了匹配这个路径要加这个路由前缀
prefix: '/post',
// cwd: process.env.CONTENT_FS_PATH,
// TODO 替换为你的仓库地址,不能使用组织仓库
repository: 'https://github.com/aatrooox/Blog',
// TODO 替换为你的 token在 github > settings > developers settings > personal access tokens
authToken: process.env.CONTENT_REPO_TOKEN
},
// md 文件的元信息,根据自己的实际情况来,这些字段会用作数据库中的表头
schema: z.object({
date: z.date(),
lastmod: z.date(),
tags: z.array(z.string()),
versions: z.array(z.string()),
})
}),
```
`env`
MySQL、Redis 环境,具体操作可以参考[这篇文章](https://zzao.club/post/nuxt/local-init-mysql-by-docker)
Redis 没有配置时,默认连接 localhost 6379 端口,本地同生产(单体数据库服务,不对外开放端口)
```
DATABASE_URL=mysql://root:root@127.0.0.1:3306/blog
NUXT_FEISHU_WEBHOOK=
NUXT_FEISHU_USER_ID=
```
先启动 MySQL、Redis
## 使用 Drizzle 初始化数据库和表结构
```bash
# 方式一:使用迁移(推荐)
pnpm db:migrate
# 方式二:按 schema 直接推送
pnpm db:push
```
## 启动项目
```bash
pnpm dev
```
## 生产部署
部署链路GitHub Actions 构建 -> 打包 `.output` + `pm2.config.json` + `pm2.preload.cjs` -> SSH 上传 -> 服务器 `/root/web/blog` 原地解压 -> Drizzle 迁移 -> PM2 启动 `Blog`(端口 4571
1) 服务器准备
- 安装 Node.js 20+ 与 PM2全局
- `npm i -g pm2`
- 创建目录与生产环境变量文件:
- 应用目录:`/root/web/blog`
- 环境文件:`/root/envs/blog/.env`
- 必需变量(示例):
- `DATABASE_URL=mysql://user:pass@host:3306/blog`
- `NUXT_SESSION_PASSWORD=<32位随机字符串>`
- `NUXT_JWT_SECRET=<随机字符串>`
- 可选:`REDIS_HOST``REDIS_PORT``CONTENT_REPO_TOKEN``NUXT_*`Nodemailer、OAuth GitHub、COS、飞书等
2) 配置 GitHub Secrets仓库 Settings -> Secrets and variables -> Actions
- SSH 访问:`SSH_PRIVATE_KEY``SSH_HOST``SSH_USER``SSH_PORT`
- 应用密钥与依赖:`DATABASE_URL``NUXT_SESSION_PASSWORD``NUXT_JWT_SECRET`
- 内容拉取:`CONTENT_REPO_TOKEN`(若启用 content 仓库)
- 可选通知与第三方:`NUXT_FEISHU_WEBHOOK``NUXT_FEISHU_USER_ID``NUXT_NODEMAILER_*``NUXT_OAUTH_GITHUB_CLIENT_ID/SECRET``NUXT_COS_*`
3) 触发部署
- Push 到 `main` 且提交信息包含 `chore(release)` 会自动触发(可使用 `pnpm release:patch|minor|major` 脚本生成)
4) 运行方式与端口
- PM2 使用 `pm2.config.json` 启动进程名 `Blog`,监听 `4571`
- 运行时通过 `node_args: -r ./pm2.preload.cjs` 读取 `/root/envs/blog/.env`,无需安装 `dotenv`
- 反向代理(示例 Nginx
```nginx
server {
listen 80;
server_name your.domain.com;
location / {
proxy_pass http://127.0.0.1:4571;
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;
}
}
```
5) 数据库迁移
- 工作流会在服务器上自动执行 Drizzle 迁移(优先 `dotenv-cli`,无则回退为 `source ENVFILE` + `npx drizzle-kit migrate`
- 如服务器无公网 npm可自行预先装好 `dotenv-cli`,或手动执行迁移
6) 回滚与灰度(可选)
- 回滚:直接 `git revert` 上次 release 提交并 push同样会触发部署
- 灰度:仓库包含 `pm2.canary.json`4572 端口),如需金丝雀发布可另行添加对应 Workflows 与目录(例如 `/root/web/blog-canary`
7) 常见排查
- 启动异常:`pm2 logs Blog` 查看日志
- 环境变量未生效:确认 `/root/envs/blog/.env` 存在且键名正确;`pm2 env 0`/`pm2 describe Blog` 检查进程环境
- 无法连接数据库/Redis验证 `DATABASE_URL`、`REDIS_HOST/PORT` 与网络策略
## 发布
> 注意 0.x 版本会有不同
```bash
# 1.0.0 => 1.0.1 0.1.0 => 0.1.1
pnpm release:patch
# 1.0.0 => 1.1.0 0.1.0 => 0.1.1
pnpm release:minor
# 1.0.0 => 2.0.0 0.1.0 => 0.2.0
pnpm release:major
```
## 自定义字体
使用自定义字体,要注意 format 的值:
```
.woff 文件:使用 format('woff')
.woff2 文件:使用 format('woff2')
.ttf 文件:使用 format('truetype')
.otf 文件:使用 format('opentype')
.eot 文件:使用 format('embedded-opentype')
.svg 文件:使用 format('svg')
```
## 关于环境变量
`.env` 文件用于开发、构建、生成期间。
生产环境如何设置环境变量,取决于你的生产环境是什么。
因为有些 `serverless` / `cf worker` 环境下没有传统的文件系统,所以 `nuxt` 选择不维护环境变量的生产环境配置。
### Nuxt 交流群
- 小群(少于 50 人)
- 分享 Nuxt 相关高质量资料
- 探讨 Nuxt 的各种问题
- 分享自己在做的项目
![](githubAssets/wxgroup.png)