Document the deployment to todolist.qingruxu.xyz: architecture, autostart config, ops commands, password rotation, backup, and redeploy steps. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
110 lines
3.6 KiB
Markdown
110 lines
3.6 KiB
Markdown
# 部署文档
|
||
|
||
> 生产环境部署记录与运维手册。目标:`todolist.qingruxu.xyz`(阿里云 ECS,Ubuntu)。
|
||
|
||
## 架构
|
||
|
||
```
|
||
浏览器 ── HTTPS (443) ──> Nginx 反代 ──> 127.0.0.1:6754 ──> Docker 容器 (uvicorn:8000)
|
||
```
|
||
|
||
- 容器只绑定 `127.0.0.1:6754`,**不对外暴露**,只能通过 Nginx 访问。
|
||
- Nginx 终止 HTTPS(Let's Encrypt 证书),反代到容器。
|
||
- 数据持久化在 Docker 命名卷 `ppm-data`。
|
||
- 应用开启 fail-secure 认证:未设密码拒绝启动;当前用 `PPM_PASSWORD_HASH` 配置。
|
||
|
||
## 服务器信息
|
||
|
||
| 项 | 值 |
|
||
|---|---|
|
||
| SSH | `root@qingruxu.xyz`(22 端口,免密) |
|
||
| 部署目录 | `/opt/progress-monitor/` |
|
||
| 容器名 | `progress-monitor` |
|
||
| 镜像 | `progress-monitor:latest` |
|
||
| 对外域名 | `https://todolist.qingruxu.xyz` |
|
||
| 容器端口 | `127.0.0.1:6754` |
|
||
| Nginx 配置 | `/etc/nginx/sites-available/todolist` |
|
||
| SSL 证书 | `/etc/letsencrypt/live/todolist.qingruxu.xyz/`(2026-11-22 到期,自动续期) |
|
||
|
||
## 开机自启
|
||
|
||
已配置,无需额外操作:
|
||
|
||
- `systemctl is-enabled docker` = `enabled`(Docker 服务随系统自启)
|
||
- 容器 `restart: unless-stopped`(Docker 启动后自动拉起容器)
|
||
|
||
**验证命令**:
|
||
|
||
```bash
|
||
systemctl is-enabled docker # 应输出 enabled
|
||
docker inspect progress-monitor --format '{{.HostConfig.RestartPolicy.Name}}' # 应输出 unless-stopped
|
||
```
|
||
|
||
## 常用运维命令
|
||
|
||
```bash
|
||
cd /opt/progress-monitor
|
||
|
||
docker-compose ps # 查看状态
|
||
docker-compose logs -f # 跟踪日志
|
||
docker-compose restart # 重启
|
||
docker-compose down # 停止并移除容器(数据卷保留)
|
||
docker-compose up -d # 启动
|
||
```
|
||
|
||
## 修改登录密码
|
||
|
||
```bash
|
||
# 1. 生成新密码哈希(任意装了 python 的机器)
|
||
python -c "from app.auth import make_password_hash; print(make_password_hash('新密码'))"
|
||
|
||
# 2. 在服务器编辑 /opt/progress-monitor/.env,替换 PPM_PASSWORD_HASH
|
||
# PPM_PASSWORD_HASH=pbkdf2_sha256$310000$...
|
||
|
||
# 3. 重启
|
||
cd /opt/progress-monitor && docker-compose up -d
|
||
```
|
||
|
||
## 数据备份
|
||
|
||
数据在 Docker 卷 `ppm-data`,可用两种方式:
|
||
|
||
**方式一:应用内导出**(推荐,登录后 ⚙ 面板 → 导出 JSON)
|
||
得到完整备份文件,可通过「导入还原」恢复。
|
||
|
||
**方式二:直接备份卷**
|
||
|
||
```bash
|
||
# 备份
|
||
docker run --rm -v progress-monitor_ppm-data:/data -v "$(pwd)":/backup alpine tar czf /backup/ppm-data-backup.tar.gz -C /data .
|
||
|
||
# 恢复
|
||
docker run --rm -v progress-monitor_ppm-data:/data -v "$(pwd)":/backup alpine tar xzf /backup/ppm-data-backup.tar.gz -C /data
|
||
```
|
||
|
||
## 部署流程(从本机到服务器,重装时参考)
|
||
|
||
```bash
|
||
# 本机
|
||
docker build -t progress-monitor:latest .
|
||
docker save progress-monitor:latest -o progress-monitor.tar
|
||
scp progress-monitor.tar docker-compose.yml .env root@qingruxu.xyz:/opt/progress-monitor/
|
||
|
||
# 服务器
|
||
cd /opt/progress-monitor
|
||
docker load -i progress-monitor.tar
|
||
docker-compose up -d
|
||
```
|
||
|
||
## 安全要点
|
||
|
||
- **fail-secure**:`.env` 未配置 `PPM_PASSWORD_HASH` 时容器拒绝启动。
|
||
- **HTTPS**:`PPM_COOKIE_SECURE=true`,会话 Cookie 仅在 HTTPS 下生效。
|
||
- **登录限流**:同 IP 5 次失败锁定 60 秒。
|
||
- **CSRF 防护**:所有写操作需 `X-CSRF-Token`。
|
||
- 不要在生产环境设置 `PPM_PASSWORD`(明文)或 `PPM_ALLOW_NO_AUTH=1`。
|
||
|
||
## 已知注意事项
|
||
|
||
- 登录限流按 IP 计数;Nginx 已透传 `X-Forwarded-For`,但 uvicorn 需开启 `--proxy-headers` 才会信任该头。当前单用户场景影响小,若未来需要精确按真实 IP 限流,需在容器 CMD 加 `--proxy-headers` 并配置信任代理。
|