NAS Docker 服务恢复排查:卷权限、端口和反代

5 月 7 日恢复一台 NAS 上的容器服务:Jellyfin、PhotoPrism、Home Assistant 都在同一个 compose 项目里。docker compose up -d 返回正常,docker compose ps 里大部分服务也是 running,但页面表现并不一致:Jellyfin 媒体库为空,PhotoPrism 新照片没有进入索引,Home Assistant 的部分设备状态不更新。

这类问题不适合只从"镜像有没有拉下来"切入。镜像入口是第一层,但 NAS 容器更容易卡在 bind mount、权限、端口和反代。下面是这次排查链路。

1. 先拆出恢复链路

我把 NAS 容器恢复拆成六层:

text 复制代码
image -> compose -> volume -> permission -> port -> reverse proxy

对应的命令:

bash 复制代码
docker compose ps
docker compose logs --tail=120
df -h
docker system df

如果磁盘满了,后面所有应用日志都可能误导人。PhotoPrism、Jellyfin 这类服务写缩略图、元数据和缓存时,对 Docker 目录和媒体目录都比较敏感。

2. 镜像入口先单独预检

节后服务恢复经常遇到一个问题:compose 一次拉多个镜像,任何一个源卡住,整组服务恢复都会被拖住。我的处理是把基础镜像拆开。

bash 复制代码
docker pull docker.1ms.run/jellyfin/jellyfin:latest
docker pull docker.1ms.run/photoprism/photoprism:latest
docker pull ghcr.1ms.run/home-assistant/home-assistant:stable
docker pull docker.1ms.run/nginx:stable-alpine

毫秒镜像(1ms.run)在这一步承担的是多源镜像入口:Docker Hub 走 docker.1ms.run,GHCR 走 ghcr.1ms.run。它解决镜像拉取链路,后续的卷、权限和反代仍然要继续排。

预检通过后再跑:

bash 复制代码
docker compose pull
docker compose up -d

3. compose 里最该先看的不是 image,而是 volumes

NAS 上 Docker 服务的长期稳定性,很多时候取决于 volume 写得够不够明确。

yaml 复制代码
services:
  jellyfin:
    image: docker.1ms.run/jellyfin/jellyfin:latest
    ports:
      - "8096:8096"
    volumes:
      - /volume1/docker/jellyfin/config:/config
      - /volume1/media:/media:ro
    restart: unless-stopped

  photoprism:
    image: docker.1ms.run/photoprism/photoprism:latest
    ports:
      - "2342:2342"
    volumes:
      - /volume1/photos:/photoprism/originals
      - /volume1/docker/photoprism/storage:/photoprism/storage
    restart: unless-stopped

  homeassistant:
    image: ghcr.1ms.run/home-assistant/home-assistant:stable
    network_mode: host
    privileged: true
    volumes:
      - /volume1/docker/homeassistant:/config
      - /etc/localtime:/etc/localtime:ro
    restart: unless-stopped

这里有两个判断:

  • Jellyfin 的媒体目录用 :ro,服务只读媒体文件,避免误写。
  • PhotoPrism 的 originals 和 storage 分开,避免把索引存储和原始照片混到一个目录里。

4. bind mount 要看容器实际拿到的路径

Docker bind mount 是把宿主机路径挂进容器。这个设计很直接,也意味着服务和宿主机目录结构强绑定。

排查时不要只看 compose 文件,直接看运行中的容器:

bash 复制代码
docker inspect jellyfin --format '{{json .Mounts}}'
docker inspect photoprism --format '{{json .Mounts}}'

再看宿主机目录:

bash 复制代码
ls -lah /volume1/media
ls -lah /volume1/photos
ls -lah /volume1/docker/photoprism/storage

如果日志里有这些词,优先回到权限和路径:

text 复制代码
permission denied
database is locked
cannot write
failed to scan directory
no such file or directory

NAS UI 里能访问目录,只代表当前登录用户能访问,不代表容器进程能访问。这个误判很常见。

5. 端口和反代分开测

Jellyfin 和 Home Assistant 这类服务,先测内网端口:

bash 复制代码
ss -lntp
curl -I http://127.0.0.1:8096
curl -I http://127.0.0.1:8123

如果本机端口通,再测 NAS 局域网 IP。如果局域网 IP 通,再看反代。这个顺序可以避免把 Caddy/Nginx、证书、DDNS、路由器映射全部混在一起。

反代日志:

bash 复制代码
docker logs --tail=120 nginx
docker logs --tail=120 caddy

我这次遇到的实际情况是:Jellyfin 容器本身没问题,8096 内网可访问,问题在反代 upstream 还指向了旧容器名。这个错误和镜像完全无关。

6. PhotoPrism 索引阶段要留出时间

节后导入照片和视频,PhotoPrism 的 CPU、内存、磁盘 IO 都会升高。不要看到缩略图没出来就重启容器。

bash 复制代码
docker stats
docker compose logs --tail=200 photoprism

如果日志是索引、缩略图、导入相关记录,且没有持续权限报错,可以先等任务跑完。真正要处理的是 storage 不可写、originals 不可读、数据库连接异常。

7. 复盘

这次恢复最后确认了三类问题:

层级 现象 处理
image GHCR 镜像拉取慢 换成 ghcr.1ms.run 预检
volume Jellyfin 媒体库为空 修正 /volume1/media 挂载路径
proxy 域名访问 502 改 Nginx upstream 容器名

NAS Docker 服务恢复的关键不是"把镜像换个前缀就完事",而是用镜像预检排除第一层不确定性,然后继续看宿主机目录、权限、端口和入口。

下次我会把这套顺序固定到恢复文档里:

text 复制代码
df -> docker pull -> compose ps -> inspect mounts -> logs -> ss -> proxy logs

它不复杂,但能避免在错误层级反复重启容器。

相关推荐
一条Go2 小时前
OnCall 时段路由:跨午夜、左闭右开与「Local 不是时区」
后端·架构·github
Moment2 小时前
不会后期的我,发现了一个开源胶片神器😍😍😍
前端·后端·开源
数据库小学妹3 小时前
pgbouncer 事务池:prepared statement、临时表与会话状态
数据库·后端·postgresql
三小河3 小时前
SWC 凭什么比 Babel 快 ?项目优化迁移踩坑记录
前端·后端
鶴哥只手遮天3 小时前
《Redis 8.10.3 深度剖析》系列 ·第 17 章. 一个迟到十六年的类型
redis·后端·开源
知守观4 小时前
同一个团队两套分包:DDD 四层落地后,domain 层最大的类还是 5885 行
java·后端·领域驱动设计
Anymous4 小时前
我手写的 Redis 锁,输给了 10 秒的 TTL
后端·架构
Rain的Java大神之路5 小时前
设计一套生产级 API 接口:从契约、安全、幂等到限流,我踩过的坑都在这了
java·后端·面试
SimonKing5 小时前
零配置也能白嫖前沿大模型!dsh-our-free-model插件真香警告
java·后端·程序员
nice_lcj5205 小时前
【从零理解 Spring AI · 15】让检索更准:先宽召回,再精排序
java·后端·rag·spring ai·ai应用开发·检索优化·重排序