Files
blog/write-server/README.md
T
2026-06-22 14:04:35 +08:00

276 lines
6.4 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`
## 功能模块
| 模块 | 路径 | 说明 |
|------|------|------|
| 文章管理 | `/` | 列表、搜索、编辑、删除、预览 |
| 撰写文章 | `/edit` | Markdown 编辑器,图片上传 |
| 评论管理 | `/comments` | Artalk 评论回复、删除 |
| 订阅源 | `/feeds` | RSS 订阅源管理 |
| 友链管理 | `/links` | 友链增删改查 |
| 图片管理 | `/images` | 图片上传管理 |
| 公众号 | `/wechat` | 微信公众号发布(自包含) |
| 回收站 | `/recycle` | 已删文章恢复 |
| Bot 管理 | `/bot` | Telegram Bot / Hugo 状态 |
## 技术栈
- **框架**: Next.js 16 (Turbopack, standalone 输出)
- **样式**: Tailwind CSS 4, SEN 暖色系
- **数据**: 直接读写 Hugo Markdown 文件,无数据库
- **评论**: Artalk API v2
- **Bot**: Telegram Bot (长轮询)
- **公众号**: 微信 API 直连(不依赖外部服务)
- **反向代理**: Nginx + Basic Auth + Service Worker
- **Hugo 预览**: 独立端口 1313,HTTPS 访问
## 目录结构
```
write-server/
├── src/ # 源代码
│ ├── app/ # Next.js 页面和 API
│ ├── components/ # React 组件
│ └── lib/ # 核心库(posts, recycle, bot, wechat, hugo)
├── nginx/ # Nginx 配置
│ ├── conf.d/ # 站点配置(主站 + Hugo 预览)
│ ├── login.html # 登录页面
│ └── sw.js # Service Worker(认证)
├── entrypoint.sh # Docker 入口脚本(权限修复)
├── Dockerfile # Docker 镜像
├── docker-compose.yml # Docker Compose
├── .env.example # 环境变量模板
└── .htpasswd # Basic Auth 密码文件
```
## 端口说明
| 端口 | 用途 | 协议 |
|------|------|------|
| 80 | HTTP → HTTPS 重定向 | HTTP |
| 443 | 写作后台(nginx 代理 → 8016) | HTTPS |
| 1313 | Hugo 预览(nginx 代理 → 容器内 1313) | HTTPS |
| 8016 | write-server(仅容器内部) | - |
## 环境变量 (.env)
```bash
# 评论系统
ARTALK_SERVER=https://artalk.usj.cc
ARTALK_SITE=优世界
# Telegram Bot
TG_BOT_TOKEN=your-bot-token
TG_ALLOWED_CHAT_IDS=your-chat-id
# 微信公众号(自包含,直连微信 API)
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
DEEPSEEK_MODEL=deepseek-chat
# 其他
DEFAULT_AUTHOR=小赵
PREFER_IFACE=eth0
```
## 常用命令
```bash
# 启动
docker compose up -d
# 停止
docker compose down
# 重建(代码/Dockerfile 变更后)
docker compose down
docker compose build --no-cache
docker compose up -d
# 查看日志
docker logs write-server -f
docker logs write-nginx -f
# 重启单个服务
docker compose restart write-server
docker compose restart nginx
```
---
## 迁移到新服务器
### 1. 新服务器准备
```bash
# 安装 Docker
curl -fsSL https://get.docker.com | sh
systemctl enable docker
systemctl start docker
# 安装 docker compose 插件
apt install -y docker-compose-plugin git
```
### 2. 克隆项目
```bash
cd ~
mkdir -p hugo && cd hugo
git clone <your-repo-url> blog
cd blog/write-server
```
### 3. 配置环境变量
```bash
cp .env.example .env
nano .env
```
填写所有必要的 Token 和 API Key。
### 4. 生成 Basic Auth 密码
```bash
docker run --rm httpd:alpine htpasswd -nbB admin "your-password" > .htpasswd
```
### 5. 配置域名 DNS
添加 A 记录指向新服务器 IP:
```
post.usj.cc → 新服务器IP
```
### 6. 申请 SSL 证书
```bash
apt install -y certbot
# 先启动 nginx(HTTP 模式)
docker compose up -d nginx
# 停 nginx 释放 80 端口
docker compose stop nginx
# 申请证书
certbot certonly --standalone -d post.usj.cc --agree-tos --email your@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/
# 启动所有服务
docker compose up -d
```
### 7. 配置防火墙
```bash
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 1313/tcp
ufw enable
```
### 8. 配置 Git
```bash
# 博客目录需要 git 可写
git config --global --add safe.directory /root/hugo/blog
```
### 9. 验证
```bash
# 检查容器状态
docker ps
# 检查 API
curl -s https://post.usj.cc/api/stats
# 检查 Hugo 预览
curl -s https://post.usj.cc:1313/ | head -5
```
### 10. 自动续期 SSL 证书
```bash
# 添加 crontab
crontab -e
# 添加:
0 3 1 * * certbot renew --quiet && docker compose restart nginx
```
---
## 迁移清单
换服务器时需要迁移的内容:
### 必须迁移
| 内容 | 位置 | 说明 |
|------|------|------|
| 博客源码 | `~/hugo/blog/` | git clone 即可 |
| write-server 代码 | `~/hugo/blog/write-server/` | git clone 即可 |
| .env 文件 | `write-server/.env` | 手动创建,填写 Token |
| .htpasswd 文件 | `write-server/.htpasswd` | 重新生成 |
| SSL 证书 | `nginx/ssl/` | 重新申请 |
### 可选迁移
| 内容 | 位置 | 说明 |
|------|------|------|
| 回收站数据 | `write-server/recycle/` | 30 天自动过期,可不迁移 |
| 日志 | `write-server/logs/` | 可不迁移 |
### 需要在新服务器操作
| 操作 | 说明 |
|------|------|
| DNS 解析 | 把 post.usj.cc 指向新 IP |
| SSL 证书 | 在新服务器重新申请 |
| 防火墙 | 放行 80, 443, 1313 端口 |
| git safe.directory | 新服务器执行 `git config --global --add safe.directory ...` |
| 微信 IP 白名单 | 如果用公众号功能,新服务器 IP 需加入微信白名单 |
### 不需要迁移
| 内容 | 原因 |
|------|------|
| Docker 镜像 | 新服务器重新构建 |
| node_modules | Docker 构建时自动安装 |
| .next 目录 | Docker 构建时自动生成 |
| Hugo 二进制 | Dockerfile 自动安装 |
---
## 已知限制
- Hugo 预览和写作后台共用域名,Hugo 导航链接只在 1313 端口有效
- Telegram Bot 通过 Docker 挂载的 SSH 密钥进行 git push
- 博客目录 owner 会被 entrypoint 改为 uid 1001(nextjs 用户)
- 3 小时登录过期(localStorage + Service Worker 双重检查)
## License
MIT