# 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 ```