166 lines
4.1 KiB
Markdown
166 lines
4.1 KiB
Markdown
|
|
# 部署指南 · DEPLOY
|
||
|
|
|
||
|
|
目标:从一台全新的 Ubuntu 24 香港 VPS,到能访问的私人新闻系统。
|
||
|
|
|
||
|
|
## 0. 准备
|
||
|
|
|
||
|
|
- 香港 VPS(最低 2C2G 30G)
|
||
|
|
- 域名(可选,没域名走 IP + 自签证书)
|
||
|
|
- 腾讯云账号 + 已开通「文本翻译 TMT」
|
||
|
|
|
||
|
|
## 1. 服务器初始化
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# SSH 登录
|
||
|
|
ssh root@YOUR_SERVER_IP
|
||
|
|
|
||
|
|
# 创建非 root 用户
|
||
|
|
adduser news
|
||
|
|
usermod -aG sudo news
|
||
|
|
|
||
|
|
# 基础包
|
||
|
|
apt update && apt -y upgrade
|
||
|
|
apt -y install curl git ufw fail2ban
|
||
|
|
|
||
|
|
# 防火墙
|
||
|
|
ufw allow OpenSSH
|
||
|
|
ufw allow 80/tcp
|
||
|
|
ufw allow 443/tcp
|
||
|
|
ufw enable
|
||
|
|
|
||
|
|
# Docker
|
||
|
|
curl -fsSL https://get.docker.com | sh
|
||
|
|
usermod -aG docker news
|
||
|
|
|
||
|
|
# 退出 root,切换到 news
|
||
|
|
exit
|
||
|
|
ssh news@YOUR_SERVER_IP
|
||
|
|
```
|
||
|
|
|
||
|
|
## 2. 拉代码
|
||
|
|
|
||
|
|
```bash
|
||
|
|
sudo mkdir -p /srv/news
|
||
|
|
sudo chown news:news /srv/news
|
||
|
|
cd /srv/news
|
||
|
|
git clone <你的仓库地址> .
|
||
|
|
# 或者 scp 上传
|
||
|
|
```
|
||
|
|
|
||
|
|
## 3. 配置环境变量
|
||
|
|
|
||
|
|
```bash
|
||
|
|
cp .env.example .env
|
||
|
|
nano .env
|
||
|
|
```
|
||
|
|
|
||
|
|
**必填字段:**
|
||
|
|
|
||
|
|
| 字段 | 怎么填 |
|
||
|
|
| --- | --- |
|
||
|
|
| `POSTGRES_PASSWORD` | `openssl rand -hex 24` |
|
||
|
|
| `REDIS_PASSWORD` | `openssl rand -hex 24` |
|
||
|
|
| `JWT_SECRET` | `openssl rand -hex 64` |
|
||
|
|
| `TENCENTCLOUD_SECRET_ID` | 腾讯云控制台 → 访问管理 → API 密钥 |
|
||
|
|
| `TENCENTCLOUD_SECRET_KEY` | 同上 |
|
||
|
|
| `TENCENTCLOUD_REGION` | `ap-hongkong` |
|
||
|
|
| `DOMAIN` | 域名(可选,留空走 IP) |
|
||
|
|
|
||
|
|
## 4. 启动
|
||
|
|
|
||
|
|
```bash
|
||
|
|
docker compose up -d --build
|
||
|
|
# 等 30 秒
|
||
|
|
docker compose ps
|
||
|
|
# 全部 healthy 即可
|
||
|
|
```
|
||
|
|
|
||
|
|
## 5. 初始化
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# 5.1 数据库迁移
|
||
|
|
docker compose exec api alembic upgrade head
|
||
|
|
|
||
|
|
# 5.2 创建 owner 账号
|
||
|
|
docker compose exec api python -m app.scripts.create_user \
|
||
|
|
--username owner --password YOUR_STRONG_PASS
|
||
|
|
|
||
|
|
# 5.3 导入 5 个种子源
|
||
|
|
docker compose exec api python -m app.scripts.seed_sources
|
||
|
|
|
||
|
|
# 5.4 手动触发一次抓取(看效果)
|
||
|
|
docker compose exec worker python -c "import asyncio; from app.workers.pipeline import run_once; asyncio.run(run_once())"
|
||
|
|
|
||
|
|
# 等 1~3 分钟,刷一下
|
||
|
|
docker compose exec postgres psql -U $POSTGRES_USER -d $POSTGRES_DB -c "SELECT count(*) FROM articles;"
|
||
|
|
```
|
||
|
|
|
||
|
|
## 6. 验证清单
|
||
|
|
|
||
|
|
- [ ] 浏览器打开 `http://YOUR_IP/` 看到登录页
|
||
|
|
- [ ] 用 owner 登录成功
|
||
|
|
- [ ] Feed 列表显示 24h 内新闻(标题中英对照)
|
||
|
|
- [ ] 详情页原文+译文并列
|
||
|
|
- [ ] `/admin/sources` 能看到 5 个源
|
||
|
|
- [ ] 翻译配额仪表盘显示已用字符
|
||
|
|
- [ ] 等到凌晨,worker 自动跑批,文章数持续增长
|
||
|
|
|
||
|
|
## 7. 域名 + HTTPS(可选)
|
||
|
|
|
||
|
|
1. 域名 A 记录指向服务器 IP
|
||
|
|
2. 编辑 `.env` 填 `DOMAIN=news.example.com` + `ACME_EMAIL=you@example.com`
|
||
|
|
3. 编辑 `Caddyfile`,把 `http://{$DOMAIN}` 改成 `{$DOMAIN}`(取消注释下面块)
|
||
|
|
4. `docker compose restart caddy`
|
||
|
|
5. Caddy 自动申请 Let's Encrypt 证书
|
||
|
|
|
||
|
|
## 8. 备份
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# 每天凌晨 4 点备份到本地
|
||
|
|
cat > /srv/news/scripts/backup.sh <<'EOF'
|
||
|
|
#!/bin/bash
|
||
|
|
set -e
|
||
|
|
BACKUP_DIR=/srv/news/backups/$(date +%Y%m%d)
|
||
|
|
mkdir -p "$BACKUP_DIR"
|
||
|
|
docker compose exec -T postgres pg_dump -U $POSTGRES_USER $POSTGRES_DB | gzip > "$BACKUP_DIR/db.sql.gz"
|
||
|
|
# 保留 7 天
|
||
|
|
find /srv/news/backups -type d -mtime +7 -exec rm -rf {} +
|
||
|
|
EOF
|
||
|
|
chmod +x /srv/news/scripts/backup.sh
|
||
|
|
|
||
|
|
# 加 cron
|
||
|
|
crontab -e
|
||
|
|
# 添加一行:
|
||
|
|
# 0 4 * * * /srv/news/scripts/backup.sh
|
||
|
|
```
|
||
|
|
|
||
|
|
**强烈建议**:把 `/srv/news/backups/` 同步到腾讯云 COS / 阿里云 OSS,做异地灾备。
|
||
|
|
|
||
|
|
## 9. 升级
|
||
|
|
|
||
|
|
```bash
|
||
|
|
cd /srv/news
|
||
|
|
git pull
|
||
|
|
docker compose pull
|
||
|
|
docker compose up -d --build
|
||
|
|
docker compose exec api alembic upgrade head
|
||
|
|
```
|
||
|
|
|
||
|
|
## 10. 常见问题
|
||
|
|
|
||
|
|
**Q: 某个源一直 fail?**
|
||
|
|
A: 看 `docker compose logs worker | grep <source_slug>`,90% 是 RSS URL 失效或者被反爬。在 `sources` 表里 `enabled=false` 暂停。
|
||
|
|
|
||
|
|
**Q: 翻译字符超 500 万?**
|
||
|
|
A: 配 `.env` 的 `TENCENT_TMT_QUOTA_BUFFER=0.05`,系统在 475 万字符后自动切本地 NLLB(需启用 `LOCAL_TRANSLATE_ENABLED=true`)。
|
||
|
|
未启用本地翻译时,系统会在原文末尾标 `[本条未翻译]`。
|
||
|
|
|
||
|
|
**Q: 30G 硬盘快满了?**
|
||
|
|
A: 执行冷热分层 cron:
|
||
|
|
```sql
|
||
|
|
DELETE FROM articles WHERE published_at < now() - interval '90 day' AND duplicate_of IS NULL;
|
||
|
|
```
|
||
|
|
|
||
|
|
**Q: 怎么加新源?**
|
||
|
|
A: 网页登录 owner → `/admin/sources` → 新增。填 name / kind=rss / url=RSS 链接 / 优先级 / 抓取频率。保存后 worker 下个轮询周期自动拉。
|