Files
diary-news/DEPLOY.md
Mavis 60b062daf2 feat: initial MVP - FastAPI backend + Vue3 frontend + docker-compose
- backend: FastAPI + SQLAlchemy 2.0(async) + asyncpg + Alembic
- 7 API routes: auth/me/articles/sources/bookmarks/subscriptions/admin
- models: User/Source/Article/Bookmark/Subscription/ApiToken
- services: RSS fetcher (feedparser) + Tencent TMT translator with quota + cache + local NLLB fallback
- workers: APScheduler + asyncio pipeline (fetch -> dedupe -> insert -> translate)
- seed scripts: create_user, seed_sources (5 RSS: Reuters/BBC/Al Jazeera/NHK/DW)
- frontend: Vue 3 + Vite + Naive UI + Pinia + vue-router
- pages: Login, Feed (24h), ArticleDetail, Sources, Bookmarks, AdminSources
- deploy: docker-compose (postgres/redis/api/worker/frontend/caddy)
- docs: README, DEPLOY, architecture, acceptance
2026-06-07 21:51:01 +08:00

4.1 KiB

部署指南 · DEPLOY

目标:从一台全新的 Ubuntu 24 香港 VPS,到能访问的私人新闻系统。

0. 准备

  • 香港 VPS(最低 2C2G 30G)
  • 域名(可选,没域名走 IP + 自签证书)
  • 腾讯云账号 + 已开通「文本翻译 TMT」

1. 服务器初始化

# 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. 拉代码

sudo mkdir -p /srv/news
sudo chown news:news /srv/news
cd /srv/news
git clone <你的仓库地址> .
# 或者 scp 上传

3. 配置环境变量

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. 启动

docker compose up -d --build
# 等 30 秒
docker compose ps
# 全部 healthy 即可

5. 初始化

# 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. 编辑 .envDOMAIN=news.example.com + ACME_EMAIL=you@example.com
  3. 编辑 Caddyfile,把 http://{$DOMAIN} 改成 {$DOMAIN}(取消注释下面块)
  4. docker compose restart caddy
  5. Caddy 自动申请 Let's Encrypt 证书

8. 备份

# 每天凌晨 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. 升级

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: 配 .envTENCENT_TMT_QUOTA_BUFFER=0.05,系统在 475 万字符后自动切本地 NLLB(需启用 LOCAL_TRANSLATE_ENABLED=true)。 未启用本地翻译时,系统会在原文末尾标 [本条未翻译]

Q: 30G 硬盘快满了? A: 执行冷热分层 cron:

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 下个轮询周期自动拉。