Kyoo 5.2.1 Docker Compose 部署指南
Kyoo 5.2.1 全栈 Compose 部署 0→1 实录:7 服务镜像选型与体积清单、.env 关键项(PUBLIC_URL 与 JWT_ISSUER 联动)、四层启动验证、4 个命名卷与 pg_dump 备份恢复、等价 docker run 逐服务拆解,含 scanner 外网依赖崩溃循环与 /auth/keys 500 空报错等实测排障。
Kyoo 5.2.1 Docker Compose 部署指南
目标:从零完成 Kyoo 5.2.1 的 Docker Compose 全栈部署——镜像选型、.env 配置、启动验证、数据持久化、运维命令与实测排障全部覆盖;所有命令与回显均在 Ubuntu 24.04 LTS + Docker 29.9.2 环境实测取得,7 个服务全部实跑。
一、环境信息
- 操作系统:Ubuntu 24.04.5 LTS(x86_64)
- Docker:29.9.2(含 compose 插件 v5.6.1,
docker compose version实测可查) - Kyoo:5.2.1(官方镜像 tag
5.2,上游最新稳定版 v5.2.1,2026-08-27 发布) - 配套组件:Traefik v3.7(官方镜像)、PostgreSQL 18(官方镜像)
- 部署目录:
/opt/kyoo/(本文演示路径,可任意指定) - 入口端口:宿主机 8136 → Traefik 容器 8901(可在 compose 里改回默认 8901,本文演示用 8136 避免占用)
- 实测部署规模:7 个服务容器、1 个自定义 bridge 网络、4 个命名数据卷
⚠️ 本文主题即 Docker 部署,docker/compose 命令均为正文主体。本系列其他篇目(介绍选型/配置参数/API 使用)见文末参考链接。
二、镜像选型说明
Kyoo 官方只发布容器镜像,不提供裸机安装包,所以镜像选择空间很小、但有两个点必须说清。实测部署使用的镜像清单(docker images 回显,大小为本地实测值):
| 镜像 | tag | 本地大小 | 角色 |
|---|---|---|---|
| ghcr.io/zoriya/kyoo_front | 5.2 | 270MB | Web 前端(Nginx 托管 SPA) |
| ghcr.io/zoriya/kyoo_api | 5.2 | 364MB | 媒体库 REST API |
| ghcr.io/zoriya/kyoo_auth | 5.2 | 107MB | 认证中心(Go) |
| ghcr.io/zoriya/kyoo_scanner | 5.2 | 1.83GB | 扫描刮削(Python) |
| ghcr.io/zoriya/kyoo_transcoder | 5.2 | 9.03GB | 转码器(内嵌完整 ffmpeg) |
| traefik | v3.7 | 253MB | 入口网关 |
| postgres | 18 | 650MB | 元数据库 |
选型要点:
- 镜像仓库:全部来自官方 GitHub Container Registry(ghcr.io/zoriya/),不要使用第三方转存——scanner/transcoder 内嵌的元数据客户端与 ffmpeg 版本直接决定刮削与播放行为。
- tag 口径:官方用
5.2这种滚动次版本 tag,patch 修复(如 5.2.1)直接滚入同 tag。锁定精确版本需配合 GitHub Release 页对照发布日期。 - build 与 image 并存:官方 compose 文件里每个 Kyoo 服务同时写了
build: ./xxx与image: ghcr.io/...。首次部署不需要源码:Compose 检测到 image 存在即直接拉取镜像,build:仅在你显式执行docker compose build时才触发。实测本机从未 clone 源码,7 个服务全部由镜像启动。 - transcoder 为何 9GB:内嵌完整 ffmpeg 及常用编解码器,属正常体积;磁盘紧张也无法裁剪,这是播放能力的基础。
💡 技术拓展:转码器「硬件加速后端」有多种实现,Kyoo 通过 Compose profiles 提供四档——
后端 适用硬件 compose profile 特点 cpu 无要求 cpu(默认)兼容性最好,CPU 占用高 vaapi Intel/AMD 核显 vaapi需要 /dev/dri 设备直通 qsv Intel 核显 qsvIntel Quick Sync,同 vaapi 设备要求 nvidia NVIDIA GPU nvidia需要 CDI GPU 设备预留 本文因在无 GPU 的环境实测,采用默认
COMPOSE_PROFILES=cpu。
三、前置条件
-
Docker Engine + Compose 插件。验证命令与实测回显:
$ docker --version && docker compose version Docker version 29.9.2, build a82e528 Docker Compose version v5.6.1 -
能拉取 ghcr.io 镜像(约 12.5GB 磁盘余量)。验证方式:第三节的
docker compose pull成功即证明。 -
外网可达 TheTVDB 与 TheMovieDB。这是最容易踩的坑:扫描器启动阶段就要登录 TheTVDB,纯内网环境 scanner 会反复重启(排障实录见第九节 Q1)。验证命令(在任何能联网的机器上):
$ curl -sI https://api4.thetvdb.com -o /dev/null -w "%{http_code}\n" 401返回 401 即代表网络可达(未带 API Key 被拒属正常)。实测内网隔离环境该命令返回
000(连接失败),此时要么给机器开通外网,要么放弃 Kyoo。 -
端口未占用:默认 8901(可自行改映射,本文用 8136)。验证:
ss -ltn | grep 8136无输出即可。 -
媒体目录:准备一个只读挂载给容器即可的目录,本文用
/opt/kyoo/video/,内放一个测试视频:$ ls -lh /opt/kyoo/video/ total 4.8M -rw-r--r-- 1 root root 4.8M Oct 29 01:12 Big Buck Bunny (2008).mp4
四、部署步骤
4.1 下载官方两份文件
官方发布物只有两份:docker-compose.yml 与 .env.example。在部署目录直接用 GitHub latest 链接下载:
$ mkdir -p /opt/kyoo && cd /opt/kyoo
$ wget -q https://github.com/zoriya/kyoo/releases/latest/download/docker-compose.yml
$ wget -q -O .env.example https://github.com/zoriya/kyoo/releases/latest/download/env.example
$ ls -l
total 20
-rw-r--r-- 1 root root 6110 Oct 29 01:04 docker-compose.yml
-rw-r--r-- 1 root root 4854 Oct 29 01:04 .env.example
⚠️ 若官方 GitHub 直连超时,可走代理下载:
wget -x http://192.168.1.62:7897 <URL>(experiment 实测可用渠道),或从镜像站获取。
4.2 编写 .env
把示例文件复制为 .env(名字必须以点开头、无后缀,compose 的 env_file: ./.env 按字面读它),再按需修改:
$ cp .env.example .env
本文实测使用的 .env 关键项(完整逐项含义见《Kyoo 5.2.1 配置参数详解》篇):
# 媒体库根目录(相对路径则相对 docker-compose.yml 所在目录)
LIBRARY_ROOT=./video
# 转码缓存目录(transcoder 可写,清理后可自动重建)
CACHE_ROOT=./cache
# 图片下载目录
IMAGES_PATH=./images
# 忽略扫描的路径正则(默认忽略 Downloads 目录)
LIBRARY_IGNORE_PATTERN=.*/[dD]ownloads?/.*
# 硬件加速档位:cpu / vaapi / qsv / nvidia
COMPOSE_PROFILES=cpu
# 转码 preset:越慢画质越好(vaapi 档不支持 preset)
GOCODER_PRESET=fast
# 对外访问地址(参与 JWT 签发,必须与浏览器实际访问地址一致)
PUBLIC_URL=http://localhost:8136
# 元数据库连接(默认值即可用;生产环境务必改密码)
PGUSER=kyoo
PGPASSWORD=q1w2e3r4
PGDATABASE=kyoo
PGHOST=postgres
PGPORT=5432
逐项说明:
LIBRARY_ROOT:唯一的媒体输入口,挂载进 scanner 与 transcoder 的/video(只读);CACHE_ROOT:transcoder 的转码缓存(HLS 分片等),实测映射到/cache,启动/停止/运行期会自动清理,放高速盘最佳;PUBLIC_URL:这是最容易配错的项。api 的JWT_ISSUER直接取自它(compose 中- JWT_ISSUER=${PUBLIC_URL}),auth 签发的 JWT 以它为 issuer——改端口或改域名后必须同步改这里,否则旧 token 全部失效;PG*五件套:postgres 容器用它初始化库,其余服务用它连库,两边必须一致(compose 的 postgres 服务- POSTGRES_USER=$PGUSER等已联动)。
⚠️ API Key 类敏感值不要写进
.env正文文件入库(如需提交仓库)。运行时用环境变量注入,例如:export KEIBI_APIKEY_SCANNER=$(openssl rand -base64 48)后在.env里写KEIBI_APIKEY_SCANNER=${KEIBI_APIKEY_SCANNER}不生效(compose 不会递归解引用宿主环境),正确做法是部署机本地.env不进版本库、权限收紧:chmod 600 .env。
4.3 拉取镜像
$ cd /opt/kyoo && docker compose pull
实测输出节选(首次全量拉取约 12.5GB,走 ghcr.io;已拉取过则秒级校验):
71ffe5b63607 Extracting 1B
fe5f3d0ae371 Pull complete 0B
71ffe5b63607 Pull complete 0B
Image ghcr.io/zoriya/kyoo_scanner:5.2 Pulled
4.4 启动全栈
$ docker compose up -d
💡 说明:
up -d会按depends_on顺序先起 postgres 并等其 healthcheck 通过(compose 里写的是condition: service_healthy),再起 auth/api;transcoder 的具体变体由COMPOSE_PROFILES决定(cpu档起transcoder服务)。
4.5 验证部署
四层验证,全部实测:
第一层:容器状态。 7 个服务全 Up、postgres healthy 为止(scanner 见第九节 Q1 的已知外网问题):
$ docker compose ps --format 'table {{.Name}}\t{{.Status}}'
NAME STATUS
kyoo-5.2.1-api Up 48 minutes
kyoo-5.2.1-auth Up 48 minutes
kyoo-5.2.1-front Up 48 minutes
kyoo-5.2.1-postgres Up 48 minutes (healthy)
kyoo-5.2.1-scanner Up 12 seconds
kyoo-5.2.1-traefik Up 48 minutes
kyoo-5.2.1-transcoder Up 48 minutes
第二层:健康检查端点。 api 与 auth 各有 health/ready 两个探针:
$ curl -s http://localhost:8136/api/health && echo && curl -s http://localhost:8136/api/ready && echo && curl -s http://localhost:8136/auth/ready && echo
{"status":"healthy"}
{"status":"healthy","database":"healthy"}
{"status":"healthy","database":"healthy"}
ready 比 health 多一个 database 字段,能确认元数据库连通。
第三层:Web 入口。 浏览器打开 http://localhost:8136 应出现 Kyoo 首页;命令行验证返回 200:
$ curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8136/
200
第四层:注册首个管理员。 第一个注册用户自动获得管理员权限(由 .env 的 FIRST_USER_CLAIMS 定义),实测:
$ curl -s -w "\n[%{http_code}]\n" -X POST http://localhost:8136/auth/users \
-H 'Content-Type: application/json' \
-d '{"username":"admin","email":"admin@example.com","password":"q1w2e3r4"}'
{"id":"3dcefdeb-254b-40f9-beeb-e1d7dd547241","createdDate":"2026-10-29T10:13:23.469473Z","lastUsed":"2026-10-29T10:13:23.469473Z","device":"curl","token":"W5zY5ejXbN56Ugj5goFkNkWjNapfZxfJ6_BnQ77EBzjeFWmWoO-Ygs74MGidjqOfuU8md1n2V-G4m7Rfd25_Rw"}
[201]
返回 201 并带 token 字段即部署成功,浏览器用同一账号登录即可使用界面。
五、数据持久化说明
实测 docker volume ls 显示 compose 自动创建 4 个命名数据卷(前缀为项目名规范化后的 kyoo-521-stack_):
| 卷名 | 容器内挂载点 | 内容 | 丢失影响 |
|---|---|---|---|
| kyoo-521-stack_db | postgres /var/lib/postgresql | 全部元数据(用户/媒体库/进度) | 致命:账号与媒体库全丢 |
| kyoo-521-stack_images | api /images | 刮削下载的海报/缩略图 | 可重建(重新刮削) |
| kyoo-521-stack_profile_pictures | auth /profile_pictures | 用户头像 | 可重建 |
| kyoo-521-stack_transcoder_metadata | transcoder /metadata | 探测缓存/指纹 | 可重建(自动重探测) |
两个 bind mount(跟随 .env 路径,宿主目录实测):
./video→ scanner/transcoder/video(:ro只读):你的媒体文件本体,永远不要让 Kyoo 写这个目录;./cache→ transcoder/cache:HLS 分片等临时缓存,可随时清空。
备份建议:核心是 db 卷。冷备一条命令即可(postgres 官方镜像自带 pg_dump):
$ docker exec kyoo-5.2.1-postgres pg_dump -U kyoo -d kyoo > kyoo-meta-$(date +%F).sql
$ ls -lh kyoo-meta-*.sql
-rw-r--r-- 1 root root 58K Oct 29 18:26 kyoo-meta-2026-10-29.sql
--
-- PostgreSQL database dump
--
⚠️ 备份产物开头含
\restrict行属 PostgreSQL 18 的 pg_dump 新格式标记,恢复时保持完整文件原样导入即可。
恢复思路:新环境起栈后 docker exec -i kyoo-5.2.1-postgres psql -U kyoo -d kyoo < 备份.sql,媒体目录与 .env 保持原路径即可。
六、环境变量表
以下为官方 .env.example 全部配置项的实测汇总(含义以官方源码与实测行为为准):
| 变量 | 默认值 | 作用 | 风险提示 |
|---|---|---|---|
| LIBRARY_ROOT | ./video | 媒体库根目录(scanner/transcoder 只读挂载) | 相对路径基于 compose 文件目录 |
| CACHE_ROOT | /tmp/kyoo_cache | 转码缓存目录 | 建议改到大盘/高速盘 |
| IMAGES_PATH | ./images | 海报图片下载目录 | api 卷 images 覆盖此值(容器内 /images) |
| LIBRARY_IGNORE_PATTERN | .*/[dD]ownloads?/.* | 扫描忽略路径正则 | 按需追加 sample 等关键字 |
| COMPOSE_PROFILES | cpu | transcoder 变体:cpu/vaapi/qsv/nvidia | 切换后需 up -d 重建 |
| GOCODER_PRESET | fast | 转码速度/画质权衡 preset | vaapi 档不支持 preset |
| THEMOVIEDB_API_ACCESS_TOKEN | 空 | 自备 TMDB read token | 留空用内置默认 |
| TVDB_APIKEY | 空 | 自备 TheTVDB API Key | 留空用内置默认 Key |
| TVDB_PIN | 空 | TVDB 订阅者 Pin | 可选 |
| PUBLIC_URL | http://localhost:8901 | 对外访问地址 | JWT_ISSUER 联动,改动需重建 |
| EXTRA_OIDC_REDIRECT_URLS | 空 | 额外 OIDC 回调白名单 | 官方应用/loopback 默认放行 |
| OIDC_GOOGLE_* | 注释态 | Google OIDC 接入(名称/ClientID/Secret 等 9 项) | 需 Google 控制台申请 |
| EXTRA_CLAIMS | {"permissions": ["core.read","core.play"], "verified": false} | 新注册用户默认权限 | verified=false 需管理员手动验证 |
| FIRST_USER_CLAIMS | 全量权限 JSON | 首个用户(管理员)权限 | 含 users/apikeys/scanner 全部权限 |
| GUEST_CLAIMS | {"permissions": ["core.read"], "verified": true} | 未登录游客权限 | 置空则全站需登录 |
| PROTECTED_CLAIMS | permissions,verified | 受保护 claim 名单 | 官方标注 DO NOT change |
| KEIBI_APIKEY_SCANNER | 随机串 | scanner 调 api 用的内置 API Key | 建议自行重新生成 |
| KEIBI_APIKEY_SCANNER_CLAIMS | core.read,core.write | 上述 key 的权限 | 与 scanner 职责匹配即可 |
| OTEL_EXPORTER_OTLP_ENDPOINT | 空 | OpenTelemetry 上报地址 | 不配则跳过 otel 初始化(实测日志可见) |
| PGUSER/PGPASSWORD/PGDATABASE/PGHOST/PGPORT | kyoo/password/kyoo/postgres/5432 | 元数据库连接五件套 | 生产必须改 PGPASSWORD |
| POSTGRES_URL | 空 | 整串连接串(含 SSL 参数) | 配置后优先于五件套 |
| KYOO_URL | 空 | front 调用的 API 地址 | compose 默认注入 http://api:5000/api |
| CAST_APPLICATION_ID | 空 | Chromecast 接收器 ID | 仅调试用 |
⚠️ 表中 KEIBI_APIKEY_SCANNER 为认证凭据,生产环境请用
openssl rand -base64 48自行生成并通过受控渠道注入,不要沿用任何公开示例值。
七、配置参数说明(compose 关键段解析)
官方 compose 文件约 180 行,值得理解的四段:
① 认证中间件链(api 与 transcoder 服务 labels):phantom-token 中间件把请求先转发到 auth 换 JWT——
- "traefik.http.middlewares.phantom-token.forwardauth.address=http://auth:4568/auth/jwt"
- "traefik.http.middlewares.phantom-token.forwardauth.authRequestHeaders=Authorization,Cookie,X-Api-Key,Sec-WebSocket-Protocol"
- "traefik.http.middlewares.phantom-token.forwardauth.authResponseHeaders=Authorization"
含义:客户端持会话 token/API Key 请求 /api/、/video 时,Traefik 先调 auth 的 /auth/jwt 换出正式 JWT 再转发给后端,后端只信 JWT。这就是为什么业务服务自身不实现登录逻辑。
② transcoder 锚点复用:文件顶部 x-transcoder: &transcoder-base 定义公共配置,cpu/vaapi/qsv/nvidia 四个服务用 <<: *transcoder-base 继承、仅覆写差异(profile 与硬件设备)。自选硬件档时不要直接改 transcoder 服务的 devices,而应切 COMPOSE_PROFILES。
③ postgres 健康门:
depends_on:
postgres:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${PGUSER} -d ${PGDATABASE}"]
interval: 5s
retries: 5
含义:auth/api 等到 pg_isready 通过才启动;改 PGUSER/PGDATABASE 时 healthcheck 自动跟随。
④ 端口与入口:traefik 服务 ports: - "8136:8901"(官方默认 8901:8901),容器内 8901 固定不变,宿主侧可任意改;改完必须同步 PUBLIC_URL。
八、配置文件挂载清单
实测从运行容器 docker inspect 汇总的全部挂载(宿主 → 容器):
| 宿主/卷 | 容器挂载点 | 读写 | 挂到哪个服务 |
|---|---|---|---|
./video(LIBRARY_ROOT) | /video | 只读 | scanner、transcoder |
./cache(CACHE_ROOT) | /cache | 读写 | transcoder |
| 卷 kyoo-521-stack_transcoder_metadata | /metadata | 读写 | transcoder |
| 卷 kyoo-521-stack_images | /images | 读写 | api |
| 卷 kyoo-521-stack_profile_pictures | /profile_pictures | 读写 | auth |
| 卷 kyoo-521-stack_db | /var/lib/postgresql | 读写 | postgres |
/var/run/docker.sock | 同路径 | 只读 | traefik(动态发现路由) |
⚠️ docker.sock 挂载意味着 Traefik 能控制 Docker 守护进程,这是 label 动态路由的代价;生产环境应确保宿主 Docker 访问面受控。
九、常见问题(实测排障实录)
9.1 Q1:scanner 容器反复重启,RestartCount 持续增长
现象(实测):docker ps 里 scanner 状态反复回到 "Up Less than a second",其余 6 个服务正常:
$ docker inspect kyoo-5.2.1-scanner --format 'RestartCount={{.RestartCount}}'
RestartCount=99
日志定位(docker logs kyoo-5.2.1-scanner 实测原文节选):
aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host
api4.thetvdb.com:443 ssl:default [Connect call failed ('199.59.148.6', 443)]
ERROR Application startup failed. Exiting.
根因:官方源码 scanner/scanner/providers/thetvdb.py 中 TVDB Provider 类初始化即建 ClientSession(base_url="https://api4.thetvdb.com/v4/"),且 API Key 有内置默认值兜底(self._api_key = os.environ.get("TVDB_APIKEY") or TVDB.DEFAULT_API_KEY)——不配置 TVDB_APIKEY 也会在启动时连 TheTVDB 登录,启动期连不上就直接退出,被 restart: unless-stopped 拉起后循环。
解决:给部署机开通外网(或配置可达的 HTTPS_PROXY)。实测本环境直连与代理均不可达(curl 返回 exit 7),属于环境限制无法恢复,其余 6 个服务不受影响,扫描功能需待网络恢复后自动生效(scanner 起来后才开始监控 /video)。选型启示:无法访问 TheTVDB/TheMovieDB 的纯内网环境不适合 Kyoo。
9.2 Q2:POST /auth/keys 返回 500 且 message 为空
现象(实测):按直觉把权限放在顶层字段时:
$ curl -s -w "\n[%{http_code}]\n" -X POST http://localhost:8136/auth/keys \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"name":"docdemo","permissions":["core.read"]}'
{"status":500,"message":"","details":null}
[500]
根因与解决:请求体 DTO(官方源码 auth/apikey.go 的 ApiKeyDto)字段是 name + claims,不是 permissions。改成正确结构(实测 201):
$ curl -s -X POST http://localhost:8136/auth/keys \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"name":"docdemo","claims":{"permissions":["core.read","core.play"]}}'
{"id":"ee1691bb-0946-4e90-81a3-8b176121282a","name":"docdemo","claims":{"permissions":["core.read","core.play"]},"token":"y8WgTX_qztDG-uJQbW8vZCp2aVN4g9Y82DE9Ml8HnPsNggaR-DAvPUNnJ_3mIqlagUBDUXwjwxpbwAxqAv3E9w"}
9.3 Q3:部分路径 502 Bad Gateway
现象(实测):scanner 崩溃期间访问其暴露路由:
$ curl -s -w "\n[%{http_code}]\n" http://localhost:8136/scanner/openapi.json
Bad Gateway
[502]
定位与解决:502 = Traefik 找得到路由规则但后端连不上。docker compose ps 看 scanner 在反复重启(见 Q1);修复对应服务后 502 自动消失。通用口诀:404 是没有这条路由、502 是有路由但后端挂了。
9.4 Q4:改了端口/域名后登录失效
根因:.env 的 PUBLIC_URL 是 JWT 的 issuer(compose 里 JWT_ISSUER=${PUBLIC_URL})。改端口或用域名访问后必须同步修改并重建 api/auth:
$ docker compose up -d --force-recreate api auth
9.5 Q5:compose up 报 env 文件找不到
现象:env_file: ./.env 校验失败类报错。
解决:官方 .env.example 必须改名成 .env(无后缀、以点开头),放在 docker-compose.yml 同目录。cp .env.example .env 即可。
十、等价 docker run
理解 compose 配置后,每条命令都能翻译成等价 docker run(先建网络与卷)。以下为 7 个服务的等价命令,可独立用于单服务调试:
# 0. 公共前置:网络与数据卷
docker network create --subnet 10.89.60.0/24 kyoo-5.2.1-net
docker volume create kyoo-521-stack_db
# 1. postgres(healthcheck 与 compose 一致)
docker run -d --name kyoo-postgres --network kyoo-5.2.1-net \
-e POSTGRES_USER=kyoo -e PGPASSWORD=q1w2e3r4 -e POSTGRES_PASSWORD=q1w2e3r4 \
-e POSTGRES_DB=kyoo -e POSTGRES_HOST_AUTH_METHOD=trust \
-v kyoo-521-stack_db:/var/lib/postgresql \
--health-cmd "pg_isready -U kyoo -d kyoo" \
postgres:18
# 2. auth(依赖 postgres healthy,挂 JWT 密钥相关环境)
docker run -d --name kyoo-auth --network kyoo-5.2.1-net \
-e PGUSER=kyoo -e PGPASSWORD=q1w2e3r4 -e PGDATABASE=kyoo -e PGHOST=postgres -e PGPORT=5432 \
-e PUBLIC_URL=http://localhost:8136 \
-e EXTRA_OIDC_REDIRECT_URLS=kyoo \
-v kyoo-521-stack_profile_pictures:/profile_pictures \
-l "traefik.enable=true" \
-l "traefik.http.routers.auth.rule=PathPrefix(`/auth/`) || PathPrefix(`/.well-known/`)" \
ghcr.io/zoriya/kyoo_auth:5.2
# 3. api
docker run -d --name kyoo-api --network kyoo-5.2.1-net \
-e PGUSER=kyoo -e PGPASSWORD=q1w2e3r4 -e PGDATABASE=kyoo -e PGHOST=postgres -e PGPORT=5432 \
-e JWT_ISSUER=http://localhost:8136 -e IMAGES_PATH=/images \
-v kyoo-521-stack_images:/images \
-l "traefik.enable=true" \
-l "traefik.http.routers.api.rule=PathPrefix(`/api/`)" \
ghcr.io/zoriya/kyoo_api:5.2
# 4. transcoder(cpu 档)
docker run -d --name kyoo-transcoder --network kyoo-5.2.1-net \
-e JWKS_URL=http://auth:4568/.well-known/jwks.json \
-v /opt/kyoo/video:/video:ro -v /opt/kyoo/cache:/cache \
-v kyoo-521-stack_transcoder_metadata:/metadata \
-l "traefik.enable=true" \
-l "traefik.http.routers.transcoder.rule=PathPrefix(`/video`)" \
ghcr.io/zoriya/kyoo_transcoder:5.2
# 5. scanner(外网可达时才能稳定运行,见 9.1)
docker run -d --name kyoo-scanner --network kyoo-5.2.1-net \
-e KYOO_URL=http://traefik:8901/api \
-e KYOO_APIKEY="$KEIBI_APIKEY_SCANNER" \
-e JWKS_URL=http://auth:4568/.well-known/jwks.json \
-e JWT_ISSUER=http://localhost:8136 \
-v /opt/kyoo/video:/video:ro \
ghcr.io/zoriya/kyoo_scanner:5.2
# 6. front
docker run -d --name kyoo-front --network kyoo-5.2.1-net \
-e KYOO_URL=http://api:5000/api \
-l "traefik.enable=true" \
-l "traefik.http.routers.front.rule=PathPrefix(`/`)" \
-l "traefik.http.services.front.loadbalancer.server.port=8901" \
ghcr.io/zoriya/kyoo_front:5.2
# 7. traefik(挂 docker.sock 做 label 发现)
docker run -d --name kyoo-traefik --network kyoo-5.2.1-net \
-p 8136:8901 \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
traefik:v3.7 \
--providers.docker=true --providers.docker.exposedbydefault=false \
--entryPoints.web.address=:8901 --accesslog=true
逐条说明:单服务调试时按 1→2→3→6→7 顺序即可看到页面;scanner(5)依赖外网与 KEIBI_APIKEY_SCANNER(.env 已有,docker compose exec auth env | grep KEIBI 可查);transcoder 的 /cache 目录不存在时 Docker 会自动创建。
十一、常用运维命令
全部实测可执行(部署目录 /opt/kyoo 下执行):
# 状态与日志
docker compose ps # 全栈状态(含 health)
docker compose logs -f api # 跟看 api 日志(-f 跟随)
docker compose logs --tail 50 transcoder # 最近 50 行
# 生命周期
docker compose restart scanner # 单服务重启
docker compose up -d --force-recreate api auth # 改 PUBLIC_URL 后重建
docker compose down # 停栈(保留卷)
docker compose down -v # 停栈并删卷(彻底重置,谨慎)
# 升级(官方口径:更新两份文件后)
docker compose pull && docker compose up -d # 拉新镜像并滚动重建
# 进入容器排查
docker exec -it kyoo-5.2.1-postgres psql -U kyoo -d kyoo # 进元数据库
docker exec -it kyoo-5.2.1-transcoder ffmpeg -version # 查 ffmpeg 版本
验证回显(down -v 属破坏性命令,演示用 restart 代替验证生命周期命令有效):
$ docker compose restart scanner
[+] Restarting 1/1
✔ Container kyoo-5.2.1-scanner Started
⚠️
docker compose down不删除命名卷,元数据安全;down -v会清空用户与媒体库,执行前先按第五节做 pg_dump 备份。
十二、参考链接
- 官方安装文档(INSTALLING.md):https://github.com/zoriya/Kyoo/blob/master/INSTALLING.md
- 官方 compose 与 env 下载:https://github.com/zoriya/Kyoo/releases/latest
- 本系列篇目:《Kyoo 5.2.1 介绍与选型指南》(架构与选型)、《Kyoo 5.2.1 配置参数详解》(.env 逐项深挖)、《Kyoo 5.2.1 API 使用详解》(认证与接口实测)。