diff --git a/deploy/nas/DEPLOY.md b/deploy/nas/DEPLOY.md new file mode 100644 index 0000000..50ea014 --- /dev/null +++ b/deploy/nas/DEPLOY.md @@ -0,0 +1,87 @@ +# NAS 一键部署 + +## 前置条件 + +1. **本机安装 paramiko**(仅第一次用): + +```bash +C:/Users/PF/.workbuddy/binaries/python/envs/default/Scripts/pip.exe install paramiko +``` + +2. **配置 SSH 密码**(环境变量,避免每次交互输入): + +```bash +set SSH_PASS=peng4077 +``` + +或直接交互式输入。 + +## 快速上手 + +```bash +# 完整流程:打包 → 上传 → 同步图标 → 构建 → 重启 → 体检 +SSH_PASS=peng4077 python deploy/nas/deploy.py + +# 只改了模板/静态文件,不需要重装依赖和重新编译镜像 +SSH_PASS=peng4077 python deploy/nas/deploy.py --no-build + +# 只同步 favicon 种子(NAS 无外网,靠种子才有真实图标) +SSH_PASS=peng4077 python deploy/nas/deploy.py --icons-only + +# 只看远端状态,不改任何东西 +SSH_PASS=peng4077 python deploy/nas/deploy.py --check + +# 本地打包预览(不打包进 .env/data/venv 等禁忌项) +SSH_PASS=peng4077 python deploy/nas/deploy.py --pack-only +``` + +## 环境变更 + +可覆盖的默认值: + +| 变量 | 默认 | 说明 | +|------|------|------| +| `NAS_HOST` | `192.168.1.102` | NAS IP | +| `NAS_USER` | `bwadmin` | SSH 用户名 | +| `NAS_PORT` | `22` | SSH 端口 | +| `NAS_DIR` | `/home/bwadmin/pear-admin-flask` | NAS 上的项目目录 | +| `SSH_PASS` | 交互式输入 | 密码(所有 sudo 命令共用) | + +## 脚本做了什么 + +1. **打包** — 排除 `.git`、`venv`、`data`、`.env`、`*.db`、`__pycache__`、`flask_session`、`logs`、`output` 等一次性/运行时产物;只打进源码 + 配置 + 部署文件。 +2. **上传** — 通过 SFTP 把 tar.gz 传到 NAS `/tmp`。 +3. **解包** — `sudo tar xzf` 覆盖项目目录,`chown bwadmin:bwadmin` 改属主。**刻意跳过** `deploy/nas/data`(数据卷属主 uid 1001 = 容器内 appuser,改错了容器会失去写权限)。 +4. **同步图标** — 把本地 `data/icon/` 下的真实 favicon 打进 `deploy/nas/data/icon/`(NAS 容器无外网,抓不到 favicon,必须靠种子才有真实图标)。 +5. **构建镜像** — `docker compose build`,**不加 `--pull`**(NAS 的 registry 镜像常返回 401,本地 `python:3.11-slim` 缓存已够用)。 +6. **启动容器** — `docker compose up -d`(容器会被重建,但 `deploy/nas/data` 数据卷内容原样保留)。 +7. **健康检查** — 最多等 30 次(间隔 4 秒)直到 `/healthz` 返回 200,超时不阻塞主流程。 +8. **验收** — `docker ps` + `curl /healthz` + `curl /site/`。 + +## 注意事项 + +- **密码安全**:脚本用 `-S -p '' bash -lc` 方式给 sudo 喂密码,**密码不会出现在 stdout**。日志中会把密码替换成 `******`。 +- **临时包位置**:打包产物放在系统临时目录(`%TEMP%\pear-src-*.tar.gz`),项目根不留残留。 +- **构建失败处理**:源码已更新到远端,但容器仍在跑旧镜像;下次重新跑一次就行。 +- **NAS 防火墙**:确保本机到 NAS 的 22 端口可达(已验证 ping 连通)。 + +## 故障排查 + +| 现象 | 可能原因 | 处理 | +|------|----------|------| +| `paramiko 未找到` | 未安装 | 用管理 python 装一次 `pip install paramiko` | +| `docker: command not found` | sudo 没带 sudoers | 确认 NAS 上 `bwadmin` 有 `sudo` 权限(`sudo -S -p '' bash -lc whoami` 能输 `root`)| +| `ImageBuildError: python:3.11-slim: 401` | `--pull` 强制拉取 | 去掉 `--pull`,NAS 已有本地缓存 | +| 构建后模板未生效 | Docker 层缓存命中 | 加 `--no-cache` 强制重建 | +| 图标仍是字母头像 | 未同步种子 | 运行 `--icons-only`,或手动把 `data/icon/*.ico` 拷进 NAS 同目录 | +| 容器启动后 healthz 不 200 | 数据库迁移缺失 | 进容器跑 `flask db upgrade` | + +## 依赖此脚本的其他命令 + +```bash +# 查看 NAS 上当前容器状态(不动任何东西) +SSH_PASS=peng4077 python deploy/nas/deploy.py --check + +# 看本地源包里实际有什么 +SSH_PASS=peng4077 python deploy/nas/deploy.py --pack-only +```