Files
Docker/idcard-api/NAS-操作手册.md
2026-10-18 08:55:43 +08:00

9.5 KiB
Raw Permalink Blame History

Windows 操作 NAS Docker · 命令手册

针对本项目的实际环境整理(身份证识别 API 部署在飞牛 fnOS)。

本机参数

项 值
NAS IP 10.1.1.163
项目目录 /vol1/1000/Docker/idcard-api
compose 项目名 icd(镜像名 icd-idcard-api)
容器名 idcard-api
服务端口 8000(容器内 8000 映射到宿主机 8000)
宿主机用户 owen(不在 docker 组,docker 命令都要 sudo)

一、三个操作平面(最容易搞错的地方)

┌─────────────────────────────────────────────┐
│ ① Windows PowerShell(你的电脑)             │
│    能做:curl.exe 测接口、WinSCP 传文件       │
│    不能:任何 docker 命令                     │
│    提示符:PS C:\Users\Administrator>         │
├─────────────────────────────────────────────┤
│ ② NAS 宿主机(SSH 连进去)                   │
│    能做:docker / docker compose / sudo / 文件操作 │
│    登录:ssh owen@10.1.1.163                 │
│    提示符:owen@youjiala:/$                   │
├─────────────────────────────────────────────┤
│ ③ 容器内部(fnOS Docker 界面「终端」按钮)    │
│    能做:容器内的 ls / grep / cat / env       │
│    不能:docker 命令(容器里没装 docker CLI) │
│    提示符:root@c5bbd0b03ba1:/#               │
└─────────────────────────────────────────────┘

判断口诀:命令里有 docker 或要动 NAS 上的文件 → 平面 ②;只是想试试接口通不通 → 平面 ①;想偷懒看容器里某个文件 → 平面 ③(但别在里面敲 docker)。


二、快速判断表

你要做的事 在哪里执行 需要登录吗
测接口通不通(curl) Windows PowerShell ❌ 不需要
上传/覆盖代码文件 Windows(WinSCP / 资源管理器) ❌ 不需要(SFTP)
docker ps / docker logs NAS 宿主机 ✅ ssh owen@10.1.1.163
docker compose build/up NAS 宿主机 ✅ SSH
看镜像创建时间 NAS 宿主机 ✅ SSH
改 .env WinSCP 或 SSH 均可 视习惯
查看容器内 main.py NAS 宿主机 docker exec ✅ SSH
快速瞄一眼容器内文件 fnOS Docker 界面「终端」 ❌ 界面点开即可
加 docker 组免 sudo NAS 宿主机 ✅ SSH

三、Windows 连接方式

SSH 登录宿主机

ssh owen@10.1.1.163
# 首次会问 yes/no,输 yes,然后输 owen 的密码
# 退出:exit

看到提示符 owen@youjiala:/$ 就说明进去了。

传文件(WinSCP / FileZilla)

  • 协议:SFTP
  • 主机:10.1.1.163,端口 22
  • 用户:owen
  • 目标目录:/vol1/1000/Docker/idcard-api

或者在 fnOS 网页的「我的文件 → Docker → idcard-api」里直接上传。

一次性免 sudo(推荐做一次)

sudo usermod -aG docker $USER
newgrp docker          # 当前会话立即生效,不用退出重登

之后所有 docker 命令都不用加 sudo 了。本文档仍按带 sudo 写,两种都能用。


四、命令速查

1. 测试接口(Windows PowerShell)

⚠️ PowerShell 里 curl 是 Invoke-WebRequest 的别名,必须写 curl.exe。

# 健康检查
curl.exe -s http://10.1.1.163:8000/api/v1/idcard/health

# 根路径(服务信息 + 端点清单)
curl.exe -s http://10.1.1.163:8000/

# 识别(带 token)
curl.exe -X POST http://10.1.1.163:8000/api/v1/idcard/recognize ^
  -H "Authorization: Bearer 你的token" ^
  -F "file=@C:/path/idcard.jpg"

# 识别(旧版 X-API-Key 头)
curl.exe -X POST http://10.1.1.163:8000/api/v1/idcard/recognize ^
  -H "X-API-Key: 你的key" ^
  -F "file=@C:/path/idcard.jpg"

# 反向验证:不带 token 应该 401
curl.exe -X POST http://10.1.1.163:8000/api/v1/idcard/recognize ^
  -F "file=@C:/path/idcard.jpg"

^ 是 CMD 的续行符。PowerShell 用反引号 `,或者直接写成一行。

2. 首次部署(SSH)

# ① 建目录(WinSCP 已传过文件可跳过)
mkdir -p /vol1/1000/Docker/idcard-api
cd /vol1/1000/Docker/idcard-api

# ② 确认文件都在
ls -la

# ③ 配 .env(必须有 .env,.env.example 不生效)
cp .env.example .env
vi .env          # 或 WinSCP 直接编辑

# ④ 检查 compose 解析结果
sudo docker compose -p icd config | grep -A2 API_TOKENS

# ⑤ 首次构建(会装 numpy/onnxruntime,3-5 分钟)
sudo docker compose -p icd up -d --build

# ⑥ 跟踪日志
sudo docker logs -f idcard-api

3. 日常更新代码(SSH)

cd /vol1/1000/Docker/idcard-api
sudo docker compose -p icd up -d --build        # 增量构建,10-30 秒

或者用项目自带脚本(会校验镜像里的代码真的更新了):

bash /vol1/1000/Docker/idcard-api/deploy.sh

只改了 .env 或 docker-compose.yml(不需要 build):

sudo docker compose -p icd up -d

怀疑缓存坏了(全量重建,3-5 分钟):

sudo docker compose -p icd build --no-cache
sudo docker compose -p icd up -d --force-recreate

4. 排查"改了代码没生效"

这是本项目最容易踩的坑:fnOS 的「重新部署」只重建容器,不重建镜像。

# ① 容器里的代码是新版吗?0=旧代码,≥1=新代码
sudo docker exec idcard-api grep -c auth_enabled /app/app/main.py

# ② 镜像什么时候建的?
sudo docker images --format "{{.Repository}}:{{.Tag}}  {{.ID}}  创建于 {{.CreatedSince}}" | grep -i idcard

# ③ compose 项目真实工作目录(和你上传的目录一致吗?)
sudo docker inspect idcard-api --format '{{index .Config.Labels "com.docker.compose.project.working_dir"}}'

# ④ 环境变量注入情况
sudo docker exec idcard-api env | grep -E "API_TOKENS|API_KEY|CLIENT_SECRET"

# ⑤ 容器状态与端口
sudo docker ps --filter name=idcard-api

5. 日常运维(SSH)

# 实时日志
sudo docker logs -f idcard-api

# 最近 50 行
sudo docker logs --tail 50 idcard-api

# 过滤调用记录(看谁在调、耗时多少)
sudo docker logs --tail 100 idcard-api | grep "recognize by="

# 内存占用(关键:1C2G 机器要盯这个)
sudo docker stats --no-stream idcard-api

# 重启(不重新读 .env,改配置请用 up -d)
sudo docker restart idcard-api

# 停掉并删除容器 + 镜像
sudo docker compose -p icd down --rmi local

# 进容器内部 shell(在宿主机执行)
sudo docker exec -it idcard-api bash

6. 容器内部(fnOS 界面「终端」里执行)

grep -c auth_enabled /app/app/main.py     # 代码版本
ls -l --time-style=long-iso /app/app/     # 文件时间
echo $API_TOKENS                          # 环境变量

这里不能跑 docker 命令。要跑 docker,回宿主机 SSH。


五、完整流程:从改代码到生效

# ① Windows:改本地文件(WorkBuddy 生成)

# ② Windows:WinSCP 上传到 /vol1/1000/Docker/idcard-api
#    注意保持目录结构:app/、Dockerfile、docker-compose.yml 等

# ③ SSH 登录 NAS
ssh owen@10.1.1.163

# ④ 构建并启动
cd /vol1/1000/Docker/idcard-api
sudo docker compose -p icd up -d --build

# ⑤ 校验镜像里的代码真的换了(关键!别跳过)
sudo docker exec idcard-api grep -c 你的新特征字符串 /app/app/main.py

# ⑥ 退出 SSH,回 Windows 测接口
exit
curl.exe -s http://10.1.1.163:8000/api/v1/idcard/health

六、错误对照表(本对话踩过的坑)

报错 在哪发生 原因 解决
docker: command not found 容器内部 在容器里跑 docker 命令 回宿主机 SSH,或去掉 docker exec 前缀用容器内路径
permission denied ... docker.sock 宿主机 用户不在 docker 组 命令前加 sudo,或 usermod -aG docker
401 Unauthorized ... docker.fnnas.com 宿主机 build fnOS 加速源不授权,且会覆盖 daemon.json Dockerfile 用 ARG BASE_IMAGE=国内仓库全路径,绕开 daemon 配置
could not find ... dockerfile 宿主机 build Dockerfile 首行 # syntax= 触发前端镜像拉取 删掉该行
health 返回缺字段 / 行为没变化 Windows 测接口 镜像没重建,跑的还是旧镜像 必须 up -d --build,不能只「重新部署」
.env 改了不生效 宿主机 ①文件叫 .env.example ②只 restart 了 创建真正的 .env,然后 up -d(不是 restart)
curl: 无法将...识别为 cmdlet Windows curl 是 PowerShell 别名 用 curl.exe
\r: command not found 宿主机 Windows CRLF 换行 sed -i 's/\r$//' 脚本名.sh
识别返回空,前端提示"未识别到信息" C# 调用方 401 被静默吞掉(没检查状态码) C# 加鉴权头 + 检查 IsSuccessStatusCode

七、两条铁律

  1. 改代码必须 build。docker compose up -d(不带 --build)在镜像已存在时不会重新构建,只重建容器。代码改动一点都进不去。
  2. -p icd 不能省。项目名不是目录名,不带这个参数会创建新项目,容器和镜像都对不上。