Files
blog/write-server/README.md
T
2026-06-22 16:23:10 +08:00

263 lines
7.5 KiB
Markdown
Raw 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.
# Write Server
Hugo 博客的管理后台,基于 Next.js 16 + Tailwind CSS 4,Docker 容器化部署。
域名:`https://post.usj.cc`
## 功能模块
| 模块 | 路径 | 权限 | 说明 |
|------|------|------|------|
| 文章管理 | `/` | admin/user | 列表、搜索、编辑、删除、预览(user 只看自己的文章) |
| 撰写文章 | `/edit` | admin/user | Markdown 编辑器,图片上传,作者自动填充 |
| 评论管理 | `/comments` | admin/user | Artalk 评论回复、删除 |
| 图片管理 | `/images` | admin/user | 图片上传管理 |
| 回收站 | `/recycle` | admin/user | 已删文章恢复(30 天) |
| 订阅源 | `/feeds` | admin | RSS 订阅源管理 |
| 友链管理 | `/links` | admin | 友链增删改查 |
| 公众号 | `/wechat` | admin | 微信公众号发布(自包含,直连微信 API) |
| Bot 管理 | `/bot` | admin | Telegram Bot / Hugo 状态 |
| 用户管理 | `/users` | admin | 添加/删除用户、修改密码 |
## 技术栈
- **框架**: Next.js 16 (Turbopack, standalone 输出)
- **样式**: Tailwind CSS 4, SEN 暖色系
- **数据**: 直接读写 Hugo Markdown 文件,无数据库
- **认证**: Service Worker + SHA-256 密码哈希,3 小时自动过期
- **评论**: Artalk API v2 + 新评论 Telegram 推送
- **Bot**: Telegram Bot(长轮询,支持语音转文字写作)
- **公众号**: 微信 API 直连(access_token 自动管理)
- **反向代理**: Nginx + HTTPS
- **Hugo 预览**: 独立端口 1313,HTTPS 访问
## Telegram Bot 功能
| 命令 | 说明 |
|------|------|
| `/new` | 新建文章 |
| `/edit` | 编辑文章 |
| `/delete` | 删除文章 |
| `/list` | 文章列表 |
| `/publish` | 保存发布 |
| `/draft` | 保存草稿 |
| `/deploy` | 推送到线上 |
| `/links` | 友链管理 |
| `/feeds` | 订阅管理 |
| `/stats` | 网站数据 |
| 语音消息 | 自动转文字写入文章 |
| 图片/文档 | 自动保存到文章目录 |
Bot 支持多用户,通过 `TG_ALLOWED_CHAT_IDS` 配置授权。
## 用户系统
用户配置文件:`users.json`(明文写入,容器启动时自动哈希)
```json
{
"users": [
{ "username": "admin", "password": "密码", "name": "昵称", "role": "admin" },
{ "username": "user1", "password": "密码", "name": "昵称", "role": "user" }
]
}
```
- **admin**: 看所有文章,管理所有模块,可添加/删除用户
- **user**: 只看自己写的文章,只能用文章/撰写/评论/图片/回收站
修改密码:登录后在「用户管理」页面操作,或直接编辑 `users.json` 重启容器。
## 目录结构
```
write-server/
├── src/
│ ├── app/ # Next.js 页面和 API
│ │ ├── api/auth/login/ # 登录认证
│ │ ├── api/posts/ # 文章 CRUD(按用户过滤)
│ │ ├── api/users/ # 用户管理
│ │ ├── api/rss/wechat/ # 微信公众号发布
│ │ ├── api/recycle/ # 回收站
│ │ ├── login/ # 登录页面
│ │ └── users/ # 用户管理页面
│ ├── components/ # React 组件
│ │ ├── AppShell.tsx # 布局(登录页/主界面切换)
│ │ ├── AuthGuard.tsx # 登录状态检查
│ │ ├── PostEditor.tsx # 文章编辑器
│ │ └── Sidebar.tsx # 侧边栏(按角色显示菜单)
│ └── lib/
│ ├── auth.ts # 认证(SHA-256 哈希)
│ ├── posts.ts # 文章读写
│ ├── recycle.ts # 回收站
│ ├── wechat.ts # 微信 API 直连
│ ├── voice.ts # 语音转文字
│ ├── hugo.ts # Hugo Server 管理
│ └── bot/ # Telegram Bot
│ ├── poll.ts # 消息轮询
│ ├── handlers.ts # 命令处理
│ └── notify.ts # 新评论推送
├── nginx/
│ ├── conf.d/
│ │ ├── write-server.conf # 主站配置
│ │ └── hugo-preview.conf # Hugo 预览 HTTPS
│ └── sw.js # Service Worker(认证)
├── users.json # 用户配置
├── entrypoint.sh # Docker 入口(权限修复 + 密码哈希)
├── Dockerfile
└── docker-compose.yml
```
## 端口说明
| 端口 | 用途 | 协议 |
|------|------|------|
| 80 | HTTP → HTTPS 重定向 | HTTP |
| 443 | 写作后台(nginx → 8016) | HTTPS |
| 1313 | Hugo 预览(nginx → 容器内 1313) | HTTPS |
## 环境变量 (.env)
```bash
# 评论系统
ARTALK_SERVER=https://artalk.usj.cc
ARTALK_SITE=优世界
# Telegram Bot
TG_BOT_TOKEN=your-bot-token
TG_ALLOWED_CHAT_IDS=7499586710,123456789
# 微信公众号(自包含)
WECHAT_APP_ID=your-app-id
WECHAT_APP_SECRET=your-app-secret
# RSS/友链 API
RSS_API_BASE=https://api.usj.cc
RSS_API_TOKEN=your-token
# AI / 语音转文字
DEEPSEEK_API_KEY=your-key
DEEPSEEK_BASE_URL=https://api.deepseek.com
# 其他
DEFAULT_AUTHOR=小赵
PREFER_IFACE=eth0
```
## 常用命令
```bash
# 启动
docker compose up -d
# 停止
docker compose down
# 重建(代码变更后)
docker compose down && docker compose build --no-cache && docker compose up -d
# 查看日志
docker logs write-server -f
# 重启单个服务
docker compose restart write-server
docker compose restart nginx
# 修改用户密码(编辑后重启即可)
nano users.json
docker compose restart write-server
```
---
## 迁移到新服务器
### 1. 安装 Docker
```bash
curl -fsSL https://get.docker.com | sh
systemctl enable docker && systemctl start docker
apt install -y docker-compose-plugin git certbot
```
### 2. 克隆项目
```bash
cd ~ && mkdir -p hugo && cd hugo
git clone <repo-url> blog
cd blog/write-server
```
### 3. 配置
```bash
# 环境变量
cp .env.example .env && nano .env
# 用户(明文密码,启动时自动哈希)
cat > users.json << 'EOF'
{
"users": [
{ "username": "admin", "password": "你的密码", "name": "小赵", "role": "admin" },
{ "username": "test", "password": "她的密码", "name": "辣辣", "role": "user" }
]
}
EOF
```
### 4. DNS + SSL
```bash
# DNS: post.usj.cc → 新服务器 IP
# SSL 证书
docker compose up -d nginx
docker compose stop nginx
certbot certonly --standalone -d post.usj.cc --agree-tos --email you@email.com
mkdir -p nginx/ssl
cp /etc/letsencrypt/live/post.usj.cc/fullchain.pem nginx/ssl/
cp /etc/letsencrypt/live/post.usj.cc/privkey.pem nginx/ssl/
```
### 5. 防火墙 + 启动
```bash
ufw allow 22,80,443,1313/tcp && ufw enable
git config --global --add safe.directory /root/hugo/blog
docker compose up -d
```
### 6. 自动续期
```bash
crontab -e
# 添加: 0 3 1 * * certbot renew --quiet && docker compose restart nginx
```
---
## 迁移清单
| 类型 | 内容 | 说明 |
|------|------|------|
| 必须 | 博客源码 | `git clone` |
| 必须 | `.env` | 手动填写 Token |
| 必须 | `users.json` | 手动创建,明文密码 |
| 必须 | SSL 证书 | 新服务器重新申请 |
| 可选 | `recycle/` | 30 天过期,可不迁移 |
| 不需要 | Docker 镜像 | 重新构建 |
| 不需要 | `node_modules` | 自动安装 |
---
## 已知限制
- Hugo 预览(1313 端口)导航链接独立,和主站不互通
- 博客目录 owner 会被 entrypoint 改为 uid 1001
- 语音转文字需要配置 `DEEPSEEK_API_KEY` 或 `WHISPER_API_KEY`
- 新评论推送每 60 秒检查一次
## License
MIT