节后恢复一台测试 NAS,上面跑了几个容器服务:Jellyfin 做媒体预览,PhotoPrism 做照片索引,Home Assistant 做设备状态面板。5 月 7 日上午恢复时,docker compose up -d 没报错,但几个服务的页面状态不一致。
这篇记录排查顺序,重点是 Docker Compose、挂载卷、端口和反向代理。
环境目标
NAS / Linux
Docker Engine
Docker Compose
Jellyfin: 8096
PhotoPrism: 2342
Home Assistant: 8123
Nginx: 80/443
基础检查:
df -h
docker version
docker compose version
docker compose ps
镜像预检
compose 里同时使用 Docker Hub 和 GHCR 镜像。为了避免整组拉取卡住,先把核心镜像拆开。
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
确认镜像层没问题后,继续执行:
docker compose pull
docker compose up -d
docker compose ps
Compose 配置片段
services:
jellyfin:
image: docker.1ms.run/jellyfin/jellyfin:latest
ports:
- "8096:8096"
volumes:
- /data/docker/jellyfin/config:/config
- /data/media:/media:ro
restart: unless-stopped
photoprism:
image: docker.1ms.run/photoprism/photoprism:latest
ports:
- "2342:2342"
volumes:
- /data/photos:/photoprism/originals
- /data/docker/photoprism/storage:/photoprism/storage
restart: unless-stopped
homeassistant:
image: ghcr.1ms.run/home-assistant/home-assistant:stable
network_mode: host
privileged: true
volumes:
- /data/docker/homeassistant:/config
- /etc/localtime:/etc/localtime:ro
restart: unless-stopped
这里把媒体、照片、配置目录分开。Jellyfin 的媒体目录只读挂载,PhotoPrism 的 originals 和 storage 分开,Home Assistant 使用 host 网络。
排查挂载卷
页面异常时,先看容器拿到的挂载,而不是只看 compose 文件。
docker inspect jellyfin --format '{
{json .Mounts}}'
docker inspect photoprism --format '{
{json .Mounts}}'
docker inspect homeassistant --format '{
{json .Mounts}}'
再看宿主机路径:
ls -lah /data/media
ls -lah /data/photos
ls -lah /data/docker
这次 Jellyfin 媒体库为空,是因为 /data/media 下面实际只有一个迁移后的空目录,真实媒体目录被挪到了 /data/video。修正挂载后重新启动 Jellyfin,媒体库恢复扫描。
排查端口和反代
先看端口:
ss -lntp
curl -I http://127.0.0.1:8096
curl -I http://127.0.0.1:2342
curl -I http://127.0.0.1:8123
内网端口通以后,再看 Nginx:
docker logs --tail=120 nginx
一个 502 是 upstream 写了旧容器名。改完 upstream 后,只重载 Nginx,不需要重启所有业务容器。
复盘
这次恢复里真正的问题有三个:
| 问题 | 表现 | 处理 |
|---|---|---|
| 镜像源不稳定 | docker compose pull 慢 |
先拆镜像预检 |
| 挂载路径变更 | Jellyfin 媒体库为空 | 修正 bind mount |
| 反代上游过期 | 域名访问 502 | 更新 Nginx upstream |
最终保留下来的顺序:
磁盘 -> 镜像 -> compose -> mount -> 权限 -> 端口 -> 反代 -> 应用日志
NAS 或测试机上跑容器服务时,不要把所有异常都归到 Docker。Docker 负责进程和镜像,数据还在宿主机目录,入口还在网络和反代。分层排查能少走很多弯路。