FlixMedia · 开始使用

部署指南

Docker 部署、和面板的组合方式、网络、挂载、硬件转码、升级与备份。

前提

  • Docker 和 Docker Compose。
  • 一个 PostgreSQL 16+(compose 示例里已经带了;也可以用自己已有的实例,把连接串填进 DATABASE_URL)。
  • FlixPilot 面板是可选的:不接面板也能单独运行。接面板时,FlixMedia 向它校验登录、取 TMDB 密钥和网盘直链。
  • FlixMedia 有自己的数据目录,和面板分开;只有 mediaserver-internal.token 是两边对话的内部密钥,由面板启动时生成,FlixMedia 只读它。

获取镜像

直接拉 Docker Hub 上发布好的镜像(amd64 / arm64,版本和更新内容见更新日志):

docker pull huanhq99/flixmedia:latest

也可以自己构建:docker build -t flixmedia .(然后把 compose 里的 image: 改成 flixmedia)。

国内网络构建默认走 rsproxy.cn 的 crates 镜像;想用官方源:--build-arg CARGO_REGISTRY=。基础镜像可用 --build-arg RUST_BASE_IMAGE=... --build-arg RUNTIME_BASE_IMAGE=... 替换成你能访问的镜像。

镜像里包含:flixmedia 二进制、ffmpeg / ffprobe、中文字体、Intel 核显驱动(仅 x86_64)。

Docker Compose

第一次启动前,在 docker-compose.yml 同目录新建 .env:

# 复制成 .env(和 docker-compose.yml 放在同一个目录),改掉下面的密码
# 密码里不要有 @ : / 这类符号,数据库连接串里会用到它
POSTGRES_PASSWORD=改成你自己的数据库密码
# FlixMedia:Emby 兼容媒体服务器(3001)。独立 compose 项目,面板(FlixPilot)另外部署
# 启动:docker compose up -d          (第一次启动前复制 .env.example 为 .env,改掉里面的数据库密码)
# 起来之后看后台「控制台」顶部的「环境自检」:挂载、网盘、TMDB 有没有问题一眼就能看到
# 更新:docker compose pull && docker compose up -d      (版本和更新内容见更新日志;要自己构建就改用 build: .)
services:
  flixmedia:
    image: huanhq99/flixmedia:latest   # Docker Hub(amd64 / arm64);想自己构建就取消下一行的注释
    # build: .
    container_name: flixmedia
    restart: unless-stopped
    depends_on:
      postgres:
        condition: service_healthy
    network_mode: host               # 局域网发现(UDP 7359)和 DLNA(UDP 1900)需要;不需要这两项可改成 ports: ["3001:3001"](同时删掉 network_mode,并把 API_UPSTREAM 改成面板的实际地址)
    # Intel 核显:硬件转码(VAAPI)和杜比视界 Profile 5 的色调映射(Vulkan)都靠它;没有核显就删掉这一段,会自动用 CPU
    devices:
      - /dev/dri:/dev/dri
    environment:
      - TZ=Asia/Shanghai
      - DATA_DIR=/app/data
      # PostgreSQL 连接串(下面的 postgres 服务;host 网络下用 127.0.0.1)。已有 SQLite 旧库的先看本页的迁移一节
      - DATABASE_URL=postgres://flixmedia:${POSTGRES_PASSWORD:-flixmedia}@127.0.0.1:5432/flixmedia
      - MEDIASERVER_PORT=3001
      # 需要代理(比如 TMDB 连不上):取消下面三行注释;NO_PROXY 要把本机和局域网写进去
      # - HTTPS_PROXY=http://192.168.1.2:7890
      # - HTTP_PROXY=http://192.168.1.2:7890
      # - NO_PROXY=127.0.0.1,localhost,192.168.0.0/16
      # FlixPilot 面板的内部地址(登录校验、TMDB 密钥、网盘直链都向它要)
      - API_UPSTREAM=http://127.0.0.1:18080
    volumes:
      # FlixMedia 自己的数据目录(数据库、转码缓存、封面等),不和面板共用
      - ./data:/app/data
      # 面板生成的内部密钥,只读挂进来,FlixMedia 靠它和面板对话
      - /path/to/flixpilot/data/mediaserver-internal.token:/app/data/mediaserver-internal.token:ro
      # 媒体文件:路径要和面板、Emby 里看到的一致
      - /path/to/strm:/strm
      # 网盘挂载由面板负责,FlixMedia 用 rslave 接收它的挂载传播
      - /path/to/CloudHub:/CloudHub:rslave
      - /path/to/CloudNAS:/CloudNAS:rslave
    healthcheck:
      test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:3001/System/Ping >/dev/null || exit 1"]
      interval: 30s
      timeout: 5s
      start_period: 70s
      retries: 3

  postgres:
    image: postgres:16-alpine
    container_name: flixmedia-postgres
    restart: unless-stopped
    ports:
      - "127.0.0.1:5432:5432"        # 只给本机的 FlixMedia 用,不对外
    environment:
      - POSTGRES_USER=flixmedia
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-flixmedia}   # 在同目录 .env 里设 POSTGRES_PASSWORD=你的密码
      - POSTGRES_DB=flixmedia
      - TZ=Asia/Shanghai
    volumes:
      - ./pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U flixmedia -d flixmedia"]
      interval: 5s
      timeout: 3s
      retries: 20

搭配面板:分成两个容器

┌────────────────────┐   内部接口 (HTTP)    ┌────────────────────┐
│ FlixPilot 面板      │ ◄──────────────────► │ FlixMedia           │
│ 3005 面板 / 8091 网关│   登录·TMDB·直链     │ 3001 Emby 兼容      │
│ 负责云盘挂载         │   管理接口代理        │ 负责媒体库与播放     │
└────────────────────┘                      └────────────────────┘
        各自的 data 目录;token 文件只读挂给 FlixMedia

好处:升级、重启面板不会打断正在播放的视频;FlixMedia 可以单独用 host 网络(局域网发现和 DLNA 需要),面板不必。

面板侧

给面板容器加:

environment:
  - MEDIASERVER_EXTERNAL=host.docker.internal:3001   # FlixMedia 的地址
ports:
  - "127.0.0.1:18080:8080"                            # 只给本机的 FlixMedia 回调,不对外
extra_hosts:
  - "host.docker.internal:host-gateway"

MEDIASERVER_EXTERNAL 告诉面板 FlixMedia 在哪里:管理接口代理、归档触发、文件变动通知都发往这个地址。面板不负责启动 FlixMedia。

FlixMedia 侧

使用上面的 compose,关键点:

项说明
network_mode: host局域网发现(UDP 7359)和 DLNA(UDP 1900 组播)在桥接网络下电视收不到。不需要这两项可以改成 ports: ["3001:3001"]
API_UPSTREAM面板的内部地址。host 网络下写 http://127.0.0.1:18080(对应面板侧映射的端口)
/app/dataFlixMedia 自己的数据目录,不和面板共用;面板的 mediaserver-internal.token 单文件只读挂进来
媒体目录路径必须和面板、Emby 里看到的一致(STRM 里写的是路径)

面板和 FlixMedia 在同一个 compose 项目里也行,但建议分成两个独立项目,各自升级。

网盘挂载

网盘由面板挂载成本地目录(FUSE)。FlixMedia 容器要看到同样的目录:

# 面板容器(挂载的提供方)
- /volume1/docker/CloudHub:/CloudHub:rshared
# FlixMedia 容器(接收挂载传播)
- /volume1/docker/CloudHub:/CloudHub:rslave

挂载一定要挂上一级普通目录并带 rslave,不要把 FUSE 里面的子目录单独挂进来,否则面板重启后会出现 Transport endpoint is not connected。

硬件转码(可选)

宿主机有 Intel 核显时,把设备映射进容器:

devices:
  - /dev/dri:/dev/dri

后台「设置 → 转码」里「硬件加速」默认是自动:检测到 /dev/dri/renderD128 就用 VAAPI,某一次失败自动退回 CPU。4K HEVC 片源在 12 代 i5 核显上实测比 CPU 快约 3.5 倍。

转码读取的是片源。网盘上的 4K 原盘读取速度往往才是瓶颈,转码本身不一定慢。

端口

端口协议用途
3001TCPEmby 兼容 API、网页界面、DLNA 描述与串流
7359UDPEmby 局域网发现(可用 MEDIASERVER_DISCOVERY=off 关闭)
1900UDPDLNA / SSDP(后台打开 DLNA 功能后才监听)

升级

# 备份数据库后拉新镜像并重建容器(先看 changelog 里这一版改了什么)
docker compose pull
docker compose up -d

升级只替换二进制,数据(PostgreSQL 里的库和 /app/data)不动;数据库表结构会在启动时自动补齐。

从旧版本(SQLite)迁移到 PostgreSQL

0.0.3 起数据库换成 PostgreSQL。已有 mediaserver.db(和 playback_reporting.db)的实例:

  • 自动导入:数据目录里有旧的 mediaserver.db、PostgreSQL 又是个空库时,启动时自动导入一次,什么都不用做。导入的结果写在启动日志里,旧文件只读、不会被改动,导入过一次就不再重复。
  • 新库里已经有数据时不会自动导入(避免覆盖)。比如先在空库上跑过初始化向导、建了媒体库,再想要旧数据,需要手动导入:
docker compose stop flixmedia
docker compose run --rm flixmedia migrate-sqlite
docker compose up -d

手动导入可以重复执行,已经存在的行会跳过;会校正自增序列,播放记录进 pr schema。旧的 .db 文件留着当备份,确认没问题再删。

备份

后台「备份还原」可以一键备份和还原整个数据库(不依赖 pg_dump):

  • 备份是一个 gzip 压缩的 mediaserver-日期-时间.fmbak 文件,放在数据目录的 backups/ 里,每天凌晨自动备份一次,按「保留份数」清理旧的。
  • 还原在一个事务里完成:先清空、再导回,中途出错整体回滚,不会把库弄坏。还原完服务会重启几秒钟。
  • 备份只包含数据库(用户、观看记录、元数据、设置),不含媒体文件、图片缓存和面板自己的数据。
  • 想做整库级别的备份(比如换服务器),也可以直接用 PostgreSQL 的工具:
docker compose exec postgres pg_dump -U flixmedia -Fc flixmedia > flixmedia-$(date +%Y%m%d).dump
docker compose exec -T postgres pg_restore -U flixmedia -d flixmedia --clean --if-exists < flixmedia-20261024.dump

不要整份复制 data 目录:里面有图片缓存、转码缓存,可能非常大。

环境自检

后台「控制台」顶部有「环境自检」,启动后也会把结果写进日志。它会检查:数据库、数据目录能不能写、ffmpeg / ffprobe、核显转码设备、每个媒体库的路径在容器里是否存在、抽查几个 STRM 指向的文件是否真的在容器里、面板连接、TMDB 连通性和响应时间、代理环境变量。

“黑屏 / 播放不了 / 刮削很慢” 先看这里,多数问题在这一屏就能看出原因(挂载没挂、网盘没就绪、连不上 TMDB 等)。

代理

程序读标准的代理环境变量,和 Emby 一样:HTTP_PROXY、HTTPS_PROXY、ALL_PROXY、NO_PROXY。设了之后所有出站请求(TMDB 等元数据来源、插件、下载)都走代理;NO_PROXY 里的地址不走,要把本机和局域网(面板、网盘服务)写进去:

    environment:
      - HTTPS_PROXY=http://你的代理地址:7890
      - HTTP_PROXY=http://你的代理地址:7890
      - NO_PROXY=127.0.0.1,localhost,192.168.0.0/16

排错

现象看哪里
登录失败API_UPSTREAM 是否指向面板、数据目录里是否有 mediaserver-internal.token;面板日志
能登录但没有网盘内容FlixMedia 容器里 ls /CloudHub/... 是否能看到;挂载是否 rslave
播放黑屏 / 播放不了控制台「环境自检」;播放器现在会直接显示原因(找不到文件时说明是哪个路径、要挂哪个目录)。STRM 里写的是 /CloudHub/... 之类的本地路径时,FlixMedia 容器里必须能看到这个路径
播放器搜不到服务器是否 host 网络;防火墙是否放行 UDP 7359
转码失败后台「设置 → 转码」是否显示 ffmpeg 可用;日志里「转码」相关行
日志级别环境变量 RUST_LOG=debug