Brave
@47c132035ed7a1105a867946b99d67af 开源软件研究 公开
讨论 Stremio Docker 插件持久化完全指南

Stremio Docker 插件持久化完全指南

Stremio 是一款免费的流媒体聚合应用,它本身不托管任何内容,而是通过插件(Add-on)从不同来源拉取电影、剧集、直播、字幕等资源。社区维护的 Docker 镜像 tsaridas/stremio-docker 将 Stremio Server、Web Player 和 FFmpeg 打包成一个轻量的 Alpine 容器,是目前最流行的自托管方案之一(Docker Hub 拉取量超过 100K+)。

但在实际使用中存在一个核心痛点: 通过 Web UI 手动安装的插件配置存储在浏览器的 localStorage 中,这意味着:

  • 🔄 更换浏览器或设备后,插件配置丢失
  • 🧹 清除浏览器缓存后,插件配置丢失
  • 🐳 容器重建后,如果浏览器缓存也被清除,插件需要重新安装
  • 🤖 无法通过 Infrastructure as Code 的方式实现自动化部署

本文将从底层原理出发,详细讲解如何通过 docker-compose.yml 一键部署并预装任意第三方插件,实现真正的持久化与可复现部署。


核心原理

要解决插件持久化的问题,首先需要理解 tsaridas/stremio-docker 镜像的内部架构和启动流程。 只有理解了数据流转的每一个环节,才能精准地在正确的位置注入配置。

🏗️ 镜像架构概览

tsaridas/stremio-docker 是一个 All-in-One 容器,内部包含三个核心组件:

组件作用端口
nginx反向代理,统一对外提供 Web UI 服务8080(对外暴露)
node server.jsStremio 流媒体引擎(EngineFS),负责种子解析、转码、缓存11470(内部 + 对外)
stremio-web(静态文件)Stremio Web Player 前端,由 nginx 托管通过 nginx 在 8080 端口提供

tsaridas/stremio-docker 的 Dockerfile 没有设置 ENTRYPOINT(为空),而是使用 CMD ["./stremio-web-service-run.sh"] 作为默认启动命令。 这意味着如果你在 docker-compose.yml 中覆盖 command,必须确保最终仍然执行 ./stremio-web-service-run.sh,否则 nginx 和 Web 服务都不会启动。

📦 localStorage.json 的数据流

理解下面这条数据流是本文最关键的部分:

📁 /srv/stremio-server/localStorage.json          ← 源文件(镜像内置默认配置)
    │
    │  ① docker-compose command 中的 node 脚本修改此文件(注入自定义插件)
    ▼
📁 /srv/stremio-server/localStorage.json          ← 修改后的源文件
    │
    │  ② stremio-web-service-run.sh 启动时复制(如设置了 SERVER_URL 还会做 sed 替换)
    ▼
📁 /srv/stremio-server/build/localStorage.json    ← nginx 实际托管的静态文件
    │
    │  ③ 浏览器加载 Web Player 时,load_localStorage.js(webpack 注入的入口脚本)
    │     通过 fetch() 请求此文件
    ▼
🌐 浏览器 localStorage                            ← Stremio Web App 的实际状态存储
    │
    │  ④ stremio-core(Rust 编译的 WASM 模块)从 localStorage 读取 profile
    │     初始化应用状态,包括已安装的插件列表
    ▼
🎬 Stremio Web Player 界面显示已安装的插件

⚠️ 踩坑警示: 如果你直接写入 build/localStorage.json,启动脚本 stremio-web-service-run.sh 会用源文件覆盖它——你的修改会被丢弃。必须修改源文件 /srv/stremio-server/localStorage.json

🧬 localStorage.json 的完整结构

localStorage.json 不是简单的插件 URL 列表。 它是对浏览器 localStorage 的完整序列化,每个顶层键对应一个 localStorage.setItem() 调用。以下是其完整结构(省略部分字段值以提高可读性):

{
  "schema_version": 16,
  "installation_id": "3dd61281a4a594b1f6eb",
  "streaming_server_urls": {
    "uid": null,
    "items": {
      "http://127.0.0.1:11470/": "2099-12-31T23:59:59.999Z"
    }
  },
  "profile": {
    "auth": null,
    "addons": [
      {
        "manifest": {
          "id": "插件唯一ID(如 com.stremio.torrentio.addon)",
          "version": "语义化版本号(如 0.0.15)",
          "name": "显示名称",
          "contactEmail": null,
          "description": "插件描述",
          "logo": null,
          "background": null,
          "types": ["movie", "series"],
          "resources": ["stream"],
          "idPrefixes": ["tt"],
          "catalogs": [],
          "addonCatalogs": [],
          "behaviorHints": {
            "adult": false,
            "p2p": false,
            "configurable": false,
            "configurationRequired": false
          }
        },
        "transportUrl": "https://插件地址/manifest.json",
        "flags": {
          "official": false,
          "protected": false
        }
      }
    ],
    "addonsLocked": false,
    "settings": {
      "interfaceLanguage": "eng",
      "streamingServerUrl": "http://127.0.0.1:11470/",
      "subtitlesLanguage": "eng",
      "audioLanguage": "eng"
    }
  }
}

🔑 关键字段详解

每个 addon 条目由三部分组成——manifesttransportUrlflags三者缺一不可,否则 stremio-core 会忽略该插件。

manifest 对象——插件的身份证:

字段必填说明
id插件唯一标识符,通常使用反向域名格式如 com.stremio.torrentio.addon
version语义化版本号
name在 UI 中显示的名称
description插件描述
resources提供的资源类型:catalog(目录)、meta(元数据)、stream(流)、subtitles(字幕)
types支持的内容类型:movieserieschannel
idPrefixesID 前缀过滤器。设为 ["tt"] 表示只响应 IMDB ID(以 tt 开头)的请求
catalogs目录定义数组。如果插件不提供目录资源,设为 []
addonCatalogs插件目录(用于在"发现插件"页面分类),一般设为 []
contactEmail联系邮箱,一般为 null
logo / background插件 logo 和背景图 URL,可为 null
behaviorHints行为提示对象,强烈建议始终提供以避免 stremio-core 解析异常

behaviorHints 对象:

字段说明
adult是否包含成人内容,用于向用户展示警告
p2p是否涉及 P2P(如 BitTorrent),使用时可能暴露用户 IP
configurable是否支持配置(设为 true 时用户可以在 UI 中点击"配置"按钮)
configurationRequired是否必须先配置才能使用

transportUrl——插件的网络入口:

这是 Stremio 客户端与插件通信的基础 URL,通常指向 manifest.json 端点。Stremio 会向 {transportUrl}/../{resource}/{type}/{id}.json 发起请求获取数据。

flags 对象:

字段说明
official是否为官方插件。第三方插件一律设为 false
protected是否受保护(不可被用户卸载)。自定义插件一般设为 false

💡 profile 的值是 JSON 对象,不是字符串。 这是最容易犯的错误之一。load_localStorage.js 会对每个顶层 key-value 做 localStorage.setItem(key, typeof value === 'object' ? JSON.stringify(value) : value),所以 profile 在文件中必须是对象形式 "profile": {...},而不是转义后的字符串 "profile": "{...}"


完整 docker-compose.yml 模板

以下是经过实际验证的、可以直接复制使用的部署配置。 核心思路是利用容器内自带的 Node.js 运行时,在启动前读取镜像原始 localStorage.json,通过 JavaScript 精确注入自定义插件,然后再执行镜像默认的启动脚本。

services:
  stremio:
    image: tsaridas/stremio-docker:latest
    container_name: stremio
    ports:
      - 8080:8080      # Web UI(nginx 反向代理)
      - 11470:11470    # Streaming Server(流媒体引擎)
    environment:
      - NO_CORS=1            # 禁用 CORS 限制,本地部署推荐开启
      - AUTO_SERVER_URL=1    # 自动从浏览器访问 URL 推断流媒体服务器地址
    volumes:
      - ./stremio-data:/root/.stremio-server   # 持久化服务器数据(缓存、设置)
    command:
      - sh
      - -c
      - |
        node -e "
        const fs = require('fs');
        const d = JSON.parse(fs.readFileSync('localStorage.json','utf8'));
        const addons = [
          {
            manifest: {
              id: 'com.stremio.torrentio.addon',
              version: '0.0.15',
              name: 'Torrentio',
              contactEmail: null,
              description: 'Provides torrent streams from scraped torrent providers',
              logo: null,
              background: null,
              types: ['movie','series'],
              resources: ['stream'],
              idPrefixes: ['tt'],
              catalogs: [],
              addonCatalogs: [],
              behaviorHints: {adult:false,p2p:true,configurable:true,configurationRequired:false}
            },
            transportUrl: 'https://torrentio.strem.fun/manifest.json',
            flags: {official:false,protected:false}
          }
        ];
        addons.forEach(a => {
          if (!d.profile.addons.some(x => x.manifest.id === a.manifest.id)) {
            d.profile.addons.splice(-1, 0, a);
          }
        });
        fs.writeFileSync('localStorage.json', JSON.stringify(d, null, 2));
        "
        exec ./stremio-web-service-run.sh
    restart: unless-stopped

🔍 逐行解读核心逻辑

为什么用 command 数组形式而不是字符串形式?

# ❌ 错误写法——YAML 字符串转义会吃掉引号,导致 shell 解析失败
command: >
  sh -c 'cat > file << EOF ... EOF && exec ./start.sh'

# ✅ 正确写法——数组形式,每个元素独立传递,不经 YAML 字符串转义
command:
  - sh          # 第一个参数:shell 解释器
  - -c          # 第二个参数:-c 标志,表示后面是要执行的脚本
  - |           # 第三个参数:YAML 字面量块,保留所有内容原样
    node -e "..."
    exec ./stremio-web-service-run.sh

为什么用 Node.js 而不是 sed / jq / 手写 JSON?

镜像基于 Alpine,默认不包含 jq,但 Node.js 是容器运行 Stremio Server 的必备依赖,一定存在。用 Node.js 操作 JSON 既安全又精确,避免了以下常见错误:

  • ❌ 手写完整 JSON(几百行,极易出错且难以维护)
  • ❌ 用 sed 做字符串替换(JSON 中的特殊字符会导致替换异常)
  • ❌ 用 echo/cat heredoc(YAML + Shell + JSON 三层转义的噩梦)

splice(-1, 0, a) 的含义:

将新插件插入到 addons 数组的倒数第一个位置之前。这是因为镜像默认配置中,Local Files 插件位于数组末尾,它负责处理本地文件,按照 Stremio 的约定应始终排在最后。

some() 防重复检查:

容器每次启动都会执行 command 中的脚本,some() 通过 manifest.id 检查插件是否已存在,避免重启后重复注入。

exec 的作用:

exec 会用 stremio-web-service-run.sh 的进程替换当前 shell 进程(而不是创建子进程)。这确保了 Docker 的 PID 1 是实际的服务进程,能正确接收 SIGTERM 等信号实现优雅停机。


如何添加新插件:三步法

📋 第一步:获取插件的 manifest 信息

在浏览器中访问插件的 manifest.json 地址。每个 Stremio 插件都必须暴露这个端点,它是插件系统的核心协议。例如访问:

https://torrentio.strem.fun/manifest.json

你会得到类似以下的 JSON 响应:

{
  "id": "com.stremio.torrentio.addon",
  "version": "0.0.15",
  "name": "Torrentio",
  "description": "Provides torrent streams from scraped torrent providers...",
  "resources": ["stream"],
  "types": ["movie", "series"],
  "idPrefixes": ["tt"],
  "catalogs": [],
  "behaviorHints": {
    "adult": false,
    "p2p": true,
    "configurable": true,
    "configurationRequired": false
  }
}

从这个响应中提取 idversionnamedescriptionresourcestypesidPrefixescatalogsbehaviorHints 字段即可。 如果某些字段(如 behaviorHints)在响应中不存在,使用默认值填充。

⚠️ 注意:部分可配置插件(如 Torrentio、MediaFusion、Comet)的 manifest URL 会包含用户自定义配置参数。 例如在 Torrentio 配置页面选择了特定种子源后,URL 会变成 https://torrentio.strem.fun/providers=yts,eztv|sort=seeders/manifest.json。此时 transportUrl 应使用这个包含配置的完整 URL。

✏️ 第二步:在 addons 数组中添加条目

docker-compose.ymlconst addons = [...] 数组中追加新条目。以下是通用模板,将注释中标记的字段替换为第一步获取的实际值即可:

{
  manifest: {
    id: 'manifest.json 中的 id 字段',
    version: 'manifest.json 中的 version 字段',
    name: 'manifest.json 中的 name 字段',
    contactEmail: null,
    description: 'manifest.json 中的 description 字段',
    logo: null,
    background: null,
    types: ['从 manifest.json 的 types 字段复制'],
    resources: ['从 manifest.json 的 resources 字段复制'],
    idPrefixes: ['从 manifest.json 获取,多数为 tt'],
    catalogs: [],
    addonCatalogs: [],
    behaviorHints: {
      adult: false,
      p2p: false,         // 涉及种子流的插件设为 true
      configurable: false, // 有配置页面的插件设为 true
      configurationRequired: false
    }
  },
  transportUrl: 'manifest.json 的完整 URL',
  flags: {official: false, protected: false}
}

💡 关于 catalogs 字段: 即使原始 manifest.json 返回了复杂的 catalogs 定义(如 Cinemeta 的电影/剧集分类),在此处也可以简化为空数组 []catalogs 只在"发现"页面的浏览功能中使用,不影响流媒体搜索和播放。 但如果你希望插件提供的分类目录也能正常显示(比如 Anime Kitsu 的"热门动漫"目录),则需要保留完整的 catalogs 数据。

🚀 第三步:重新部署

docker compose down && docker compose up -d

首次部署或更换插件后,需要清除浏览器缓存或使用无痕模式访问 http://你的IP:8080。这是因为浏览器可能缓存了旧的 localStorage 数据,其中不包含新插件。


实战示例:同时部署多个插件

以下示例演示如何在 docker-compose.yml 中一次性预装 Torrentio(种子流)+ Anime Kitsu(动漫目录)两个第三方插件。只需在 addons 数组中添加多个条目即可,注入脚本会逐个检查并添加:

    command:
      - sh
      - -c
      - |
        node -e "
        const fs = require('fs');
        const d = JSON.parse(fs.readFileSync('localStorage.json','utf8'));
        const addons = [
          {
            manifest: {
              id: 'com.stremio.torrentio.addon',
              version: '0.0.15',
              name: 'Torrentio',
              contactEmail: null,
              description: 'Provides torrent streams from scraped torrent providers',
              logo: null,
              background: null,
              types: ['movie','series'],
              resources: ['stream'],
              idPrefixes: ['tt'],
              catalogs: [],
              addonCatalogs: [],
              behaviorHints: {adult:false,p2p:true,configurable:true,configurationRequired:false}
            },
            transportUrl: 'https://torrentio.strem.fun/manifest.json',
            flags: {official:false,protected:false}
          },
          {
            manifest: {
              id: 'anime-kitsu',
              version: '0.0.1',
              name: 'Anime Kitsu',
              contactEmail: null,
              description: 'Unofficial Kitsu.io anime catalog addon',
              logo: null,
              background: null,
              types: ['anime'],
              resources: ['catalog','meta'],
              idPrefixes: ['kitsu:'],
              catalogs: [],
              addonCatalogs: [],
              behaviorHints: {adult:false,p2p:false,configurable:false,configurationRequired:false}
            },
            transportUrl: 'https://anime-kitsu.strem.fun/manifest.json',
            flags: {official:false,protected:false}
          }
        ];
        addons.forEach(a => {
          if (!d.profile.addons.some(x => x.manifest.id === a.manifest.id)) {
            d.profile.addons.splice(-1, 0, a);
          }
        });
        fs.writeFileSync('localStorage.json', JSON.stringify(d, null, 2));
        "
        exec ./stremio-web-service-run.sh

要点: 多个插件条目之间用逗号分隔,addons.forEach() 会逐个处理,每个都有独立的 some() 防重复检查。


常用第三方插件速查表

以下插件均为非内置的社区第三方插件,需要手动添加。镜像默认已内置 Cinemeta、YouTube、WatchHub、Public Domain Movies、OpenSubtitles v3、Local Files 六个官方插件,无需额外配置。

🎬 流媒体源(Stream)

这类插件提供视频流链接,是实际观看内容的核心。

插件manifest URLid说明
Torrentiohttps://torrentio.strem.fun/manifest.jsoncom.stremio.torrentio.addon最流行的种子流插件。 聚合 YTS、EZTV、RARBG、1337x、ThePirateBay 等 20+ 种子站源。支持 RealDebrid、AllDebrid、Premiumize 等 Debrid 服务。高度可配置,可在 配置页面 自定义种子源、排序方式、画质过滤等
MediaFusionhttps://mediafusion.elfhosted.com/manifest.jsonmediafusionTorrentio 的强力替代品。 支持电影、剧集、直播和体育赛事。特色功能包括用户数据加密、Watchlist 同步、MediaFlow 代理、M3U 播放列表导入。可自托管或使用 ElfHosted 公共实例。在 配置页面 自定义后会生成包含配置的个性化 manifest URL
Comet需配置后获取配置后确定注重速度和效率的 Debrid 流插件。 支持 RealDebrid、AllDebrid、Premiumize。可通过 Prowlarr/Jackett 添加自定义索引器,使用 Zilean 抓取 DMM 内容,支持 RTN 智能种子排序。在 配置页面 自定义文件大小、索引器、分辨率等设置后生成 manifest URL
AIOStreams需配置后获取配置后确定聚合器中的聚合器。 将 Torrentio、MediaFusion、Comet 等多个流插件的结果合并、去重、排序后统一返回。适合想要一站式获取所有源的用户

📚 内容目录(Catalog)

这类插件提供内容浏览和搜索目录,帮助你发现新内容。

插件manifest URLid说明
Anime Kitsuhttps://anime-kitsu.strem.fun/manifest.jsonanime-kitsu非官方 Kitsu.io 动漫目录。提供"全部"、"评分最高"、"最受欢迎"、"热门趋势"等分类。使用 kitsu: 作为 ID 前缀
Torrent Catalogshttps://torrent-catalogs.strem.fun/manifest.jsontorrent-catalogs基于种子热度的电影/剧集/动漫目录,按做种数排序。需配合 Anime Kitsu 使用动漫目录功能
Cyberflix Catalog需在社区目录查找视配置而定提供小众电影和剧集的分类目录,社区支持活跃
RPDB Catalogs需配置后获取视配置而定使用 Rating Poster Database 为目录提供包含评分信息的海报图片

📺 直播与 IPTV

插件manifest URLid说明
Xtremio需配置后获取视配置而定兼容 M3U URL 和 Xtream Code。如果你有 IPTV 供应商信息,可以集成直播频道

💡 如何查找更多插件? 社区维护的插件目录网站 stremio-addons.net 是目前最全的第三方插件索引(原 GitHub 上的 Stremio-Community/stremio-addons-list 仓库已于 2025 年 11 月归档为只读)。你也可以在 Stremio Web UI 中点击 Add-ons → Community 浏览可用插件。

🔧 关于可配置插件的特殊处理

Torrentio、MediaFusion、Comet 等插件都提供配置页面(Configure Page)。 当你在配置页面调整参数后,生成的安装链接中会包含编码后的配置信息,例如:

# Torrentio 默认配置
https://torrentio.strem.fun/manifest.json

# Torrentio 自定义配置(只用 YTS 和 EZTV,按做种数排序)
https://torrentio.strem.fun/providers=yts,eztv|sort=seeders/manifest.json

# MediaFusion 带 Debrid 配置的个性化链接
https://mediafusion.elfhosted.com/<base64编码的配置>/manifest.json

docker-compose.yml 中,你需要将 transportUrl 设为包含你个人配置的完整 URL。 manifest 中的其他字段(idname 等)保持不变,因为它们描述的是插件本身的身份,而不是你的配置。


技术要点总结

✅ 正确做法

要点说明
📂 修改源文件 localStorage.json位于 /srv/stremio-server/localStorage.json,启动脚本会自动复制到 build/ 目录
🔧 用 Node.js 修改 JSON容器自带 Node.js 运行时,操作 JSON 安全精确,比 sed/jq/手写可靠得多
📦 profile 是 JSON 对象"profile": {...} 而不是 "profile": "{...}"。这是最常见的格式错误
📝 manifest 字段完整必须包含 behaviorHintsaddonCatalogs 等字段,即使值为空对象/空数组
🔀 splice(-1,0,...) 插入确保 Local Files 插件始终排在数组末尾
🔄 some() 防重复通过 manifest.id 判断,容器重启时不会重复注入同一插件
♻️ exec 替换进程exec ./stremio-web-service-run.sh 确保 Docker PID 1 是服务进程

❌ 常见错误

错误后果
command 直接运行 node server.js跳过 nginx、Web 服务和 localStorage 加载机制,Web UI 无法访问
写入 build/localStorage.json被启动脚本用源文件覆盖,修改丢失
profile 写成字符串化 JSONstremio-core 无法正确解析插件列表
省略 behaviorHints/addonCatalogsstremio-core 反序列化失败,插件不显示
使用 command: > sh -c '...' 字符串形式YAML + Shell + JSON 三层转义冲突,引号被吃掉

排错指南

🔍 插件安装后不显示

这是最常遇到的问题,按以下顺序排查:

  1. 清除浏览器缓存或使用无痕/隐私模式访问——浏览器可能缓存了旧的 localStorage
  2. 验证文件内容是否正确写入:

    docker exec stremio cat /srv/stremio-server/build/localStorage.json | python3 -m json.tool

    在输出的 JSON 中搜索你的插件 id,确认它存在于 profile.addons 数组中

  3. 验证 JSON 格式是否有效:

    docker exec stremio node -e "JSON.parse(require('fs').readFileSync('build/localStorage.json','utf8')); console.log('JSON valid')"

    如果输出 JSON valid 则格式正确,否则会报出具体的语法错误

🚫 容器启动失败(exit code 1)

  1. 检查 YAML 语法是否正确:

    docker compose config
  2. 确认 command 使用数组形式 [sh, -c, |],不要使用 command: > sh -c '...' 字符串形式
  3. 单独测试 Node.js 脚本是否可执行:

    docker run --rm tsaridas/stremio-docker:latest node -e "console.log('Node works')"
  4. 检查 JS 脚本中的引号——YAML | 块内部的 node -e "..." 使用双引号包裹,JS 字符串必须使用单引号,否则会导致引号冲突

🛠️ 日志中常见的正常警告

以下日志信息不是错误,可以安全忽略:

日志含义
Cannot update settings ENOENT: server-settings.json首次启动时文件不存在,服务器会自动创建
Tests failed for hw accel profile: qsv/nvenc/vaapi机器没有 GPU,硬件加速不可用,自动回退到 CPU 软解码
Buffer() is deprecatedNode.js API 弃用警告,不影响功能
Resizing cache size to 2048MB缓存初始化,正常行为

🧪 调试命令速查

# 查看镜像默认的 localStorage.json(未经修改的原始版本)
docker run --rm tsaridas/stremio-docker:latest cat /srv/stremio-server/localStorage.json

# 查看容器中实际被修改后的源文件
docker exec stremio cat /srv/stremio-server/localStorage.json

# 查看 nginx 实际托管的、浏览器最终加载的文件
docker exec stremio cat /srv/stremio-server/build/localStorage.json

# 列出当前所有已注入插件的 ID 和名称
docker exec stremio node -e "
  const d = JSON.parse(require('fs').readFileSync('build/localStorage.json','utf8'));
  d.profile.addons.forEach((a,i) => console.log(i, a.manifest.id, a.manifest.name));
"

# 查看容器启动日志
docker logs stremio --tail 50

最终进阶配置(添加FileBrowser)

services:
  stremio:
    image: tsaridas/stremio-docker:latest
    container_name: stremio
    ports:
      - 9080:8080
      - 11470:11470
    environment:
      - NO_CORS=1
      - AUTO_SERVER_URL=1
    volumes:
      - stremio_data:/root/.stremio-server
      - media_data:/root/.stremio-server/stremio-cache
    # 修复:切换到 /stremio 目录再执行相对路径脚本,确保 127 错误消失
    command:
      - sh
      - -c
      - |
        cd /stremio
        (
          node -e "
          try {
            const fs = require('fs');
            if (!fs.existsSync('localStorage.json')) fs.writeFileSync('localStorage.json', JSON.stringify({profile:{addons:[]}}));
            let d = JSON.parse(fs.readFileSync('localStorage.json','utf8'));
            if (!d.profile.addons.some(a => a.manifest.id === 'com.stremio.torrentio.addon')) {
              d.profile.addons.push({
                manifest: { id: 'com.stremio.torrentio.addon', version: '0.0.15', name: 'Torrentio', description: 'Provides torrent streams', types: ['movie','series'], resources: ['stream'], idPrefixes: ['tt'], behaviorHints: {adult:false,p2p:true,configurable:true,configurationRequired:false} },
                transportUrl: 'https://torrentio.strem.fun',
                flags: {official:false,protected:false}
              });
              fs.writeFileSync('localStorage.json', JSON.stringify(d, null, 2));
            }
          } catch (e) { console.error('Addon injection failed'); }
          "
        ) &
        ./stremio-web-service-run.sh
    restart: unless-stopped

  filebrowser:
    image: filebrowser/filebrowser:latest
    container_name: filebrowser
    ports:
      - 8081:80
    volumes:
      - media_data:/srv
      - fb_config:/config
    user: "0:0" 
    restart: unless-stopped

volumes:
  stremio_data:
  media_data:
  fb_config:

networks: {}

参考资料