自托管本地视频画廊:挂载目录即用,支持子目录、自动封面|amd64/arm64
332
一个零第三方依赖(只用 Python 标准库)的自托管视频画廊。把装着视频的文件夹挂载进容器, 就能在局域网里用浏览器浏览、播放自己的视频库。
Esc / ← → / 空格支持 linux/amd64 与 linux/arm64。
镜像里只有程序本身;你只需要把视频目录挂进去,封面会自动生成,收藏也留在挂载目录里。
docker run -d --name video-gallery \
--restart unless-stopped \
-p 8080:8080 \
-e TZ=Asia/Shanghai \
-v /srv/videos:/data/recovery/mp4 \
-v /srv/video-thumbs:/var/cache/recovery-gallery/thumbs \
-v ./state:/var/lib/recovery-gallery \
luohaonan/recovery-gallery:latest
然后打开 http://<宿主机IP>:8080。
注意:容器内固定从
/data/recovery/mp4读视频、往/var/cache/recovery-gallery/thumbs写封面,所以左边宿主机路径随你改, 右边容器路径要照抄。视频目录不存在时容器会直接启动失败(有意的,避免起来后是一片空白)。
services:
gallery:
image: luohaonan/recovery-gallery:latest
container_name: video-gallery
restart: unless-stopped
ports:
# 左边宿主机端口可改;右边要与容器内 --port 一致
- "8080:8080"
environment:
# 删除/关机要输入「当天日期」二次确认,时区必须设对
TZ: Asia/Shanghai
volumes:
# 视频目录(必须)。左边换成你自己的视频文件夹;
# 需要网页「删除」功能就要可写,纯只读播放库可加 :ro
- /srv/videos:/data/recovery/mp4
# 封面缓存(强烈建议):不挂则容器重建后要重新抽帧生成
- /srv/video-thumbs:/var/cache/recovery-gallery/thumbs
# 收藏名单 likes.json(强烈建议):不挂则删容器后收藏丢失
- ./state:/var/lib/recovery-gallery
# 时区文件(可选)
- /etc/localtime:/etc/localtime:ro
# CPU 功耗显示(可选):右上角功耗来自 Intel RAPL,虚拟机可能没有
# - /sys/devices/virtual/powercap:/sys/devices/virtual/powercap:ro
# 网页关机(可选):见「网页关机」一节
# - /run/video-gallery:/run/video-gallery
docker compose up -d
| 宿主机路径 | 容器内路径 | 说明 |
|---|---|---|
| 你的视频目录 | /data/recovery/mp4 | 必须。网页只读取这里的 .mp4 |
| 缩略图目录 | /var/cache/recovery-gallery/thumbs | 自动生成的封面缓存(文件名 <视频名>.mp4.jpg),强烈建议挂出来 |
| 收藏状态目录 | /var/lib/recovery-gallery | 收藏名单 likes.json 所在目录 |
/etc/localtime | 同左(:ro) | 时区,配合 TZ 使用 |
/sys/devices/virtual/powercap | 同左(:ro) | 可选,CPU 功耗显示 |
/run/video-gallery | 同左 | 可选,仅「网页关机」方案用 |
挂载进去的目录会递归扫描,子目录里的视频一样能看到:
📁 目录名 胶囊点一下就能只看那个目录只列出含视频的目录:某个子目录里全是文档/图片的话,它不会出现在下拉框里。 以
.开头的目录(.git、.DS_Store之类)和符号链接指向目录外的文件不会被扫描,也不能通过 URL 访问。
镜像里带了 ffmpeg,不需要你预先准备封面图:
想调整或关掉:
command:
- python3
- app.py
- --host
- 0.0.0.0
- --port
- "8080"
- --likes-file
- /var/lib/recovery-gallery/likes.json
# 从第 5 秒抽帧、宽 960、只看前台请求不跑后台补齐
- --thumb-seek
- "5"
- --thumb-width
- "960"
- --no-thumb-prewarm
# 完全不要缩略图功能:
# - --no-thumbnails
生成结果缓存在 /var/cache/recovery-gallery/thumbs,建议挂出来,
容器重建后不用重新抽帧。源码损坏、抽不出帧的视频会跳过(日志里会写明原因),
页面会退回显示动态预览。
| 名称 | 默认 | 说明 |
|---|---|---|
| 容器端口 | 8080 | 用 --port 可改,改了记得同步 compose 的端口映射 |
TZ | Asia/Shanghai | 影响「删除 / 关机」的日期确认 |
容器默认没有权限关掉宿主机,点「关机」会返回 500 —— 这是预期行为,不是 bug。
想让它真的生效,用「共享文件 + 宿主机 systemd path 单元」:
宿主机上:
mkdir -p /run/video-gallery
cat > /etc/systemd/system/video-gallery-poweroff.path <<'EOF'
[Unit]
Description=Watch video-gallery poweroff request
[Path]
PathExists=/run/video-gallery/poweroff.request
[Install]
WantedBy=paths.target
EOF
cat > /etc/systemd/system/video-gallery-poweroff.service <<'EOF'
[Unit]
Description=Poweroff requested from video-gallery
[Service]
Type=oneshot
ExecStart=/bin/rm -f /run/video-gallery/poweroff.request
ExecStart=/sbin/shutdown -h now
EOF
systemctl enable --now video-gallery-poweroff.path
compose 里放开 /run/video-gallery 挂载,并覆盖启动命令:
volumes:
- /run/video-gallery:/run/video-gallery
command:
- python3
- app.py
- --host
- 0.0.0.0
- --port
- "8080"
- --likes-file
- /var/lib/recovery-gallery/likes.json
- --poweroff-command
- touch /run/video-gallery/poweroff.request
| 参数 | 默认 | 说明 |
|---|---|---|
--host | 0.0.0.0 | 监听地址 |
--port | 8080 | 监听端口 |
--likes-file | /var/lib/recovery-gallery/likes.json | 收藏名单路径 |
--video-root | /data/recovery/mp4 | 视频目录(容器里一般不用改) |
--thumb-root | /var/cache/recovery-gallery/thumbs | 缩略图缓存目录 |
--thumbnails / --no-thumbnails | 开 | 缺封面时是否用 ffmpeg 自动抽帧 |
--thumb-prewarm / --no-thumb-prewarm | 开 | 是否后台把整个库补齐 |
--thumb-width | 640 | 缩略图宽度,高度等比 |
--thumb-seek | 1.0 | 从第几秒抽帧 |
--thumb-prewarm-delay | 15 | 启动后多久开始后台补齐(秒) |
--ffmpeg | 自动查找 | 指定 ffmpeg 可执行文件 |
--poweroff-command | /sbin/shutdown -h now | 网页「关机」执行的命令 |
| 标签 | 说明 |
|---|---|
latest | 最新构建,多架构(amd64 + arm64) |
2026-10-07 | 固定日期版本,多架构 |
amd64 / arm64 | 单架构镜像 |
docker pull luohaonan/recovery-gallery:latest
cd <源码目录>
docker build -t luohaonan/recovery-gallery:latest .
基础镜像默认 python:3.13-slim,拉取慢时可以换国内源:
docker build \
--build-arg BASE_IMAGE=docker.1ms.run/library/python:3.13-slim \
-t luohaonan/recovery-gallery:latest .
启动就退出,日志说 video directory does not exist
视频目录没挂到 /data/recovery/mp4(这个容器路径是固定的,不能改)。
端口 8080 被占用 改 compose 左边的宿主机端口,或先停掉占用 8080 的进程。
收藏重启后就没了
/var/lib/recovery-gallery 没挂出来,likes.json 落在容器可写层里了。
右上角功耗一直显示 --
没读到 Intel RAPL。虚拟机 / 部分新平台没有该传感器,属正常。
点了关机没反应 / 报 500 见上文「网页关机(可选)」,容器默认没权限关宿主机。
子目录里的视频看不到
确认文件扩展名是 .mp4(大小写都行),且路径中没有以 . 开头的目录。
封面图要等一会儿才出来 第一次访问某个视频时才会抽帧;后台补齐线程也会慢慢把整库补上。 库很大时可以先让它跑一阵,或把缩略图目录挂出来复用。
有些视频一直没有封面图
多半是文件本身损坏(日志里会打印 thumbnail: 生成失败 <名字>: ...,比如 moov atom not found)。
这类文件会跳过,页面显示动态预览。
Content type
Image
Digest
sha256:c44e8134f…
Size
95.2 MB
Last updated
1 day ago
docker pull luohaonan/recovery-gallery