iHub Docs

iHub Docs · 1.6.x

使用文档

从部署、首次初始化,到消息接入、音乐、影视、书架、文件与容器。内容按 iHub 1.6.x 的实际界面与接口整理;遇到问题先看最后的「常见问题」。

适用于 iHub 1.6.x · 最近更新 2026-10-18

概览

iHub 是一个自托管的个人数字生活中枢。它把短信、邮箱和设备通知收进同一条消息时间线,并在同一个站点里提供音乐、影视、书架、文件、导航与容器管理。所有数据放在你自己的机器上,一个账号、一个界面、一个数据目录。

模块作用可选依赖
消息中心短信 / IMAP 邮箱 / API 通知聚合,搜索、未读、星标、置顶、批量与回收站IMAP 邮箱、短信设备或硬件网关
总览消息聚合、常用导航、快传、容器速览、继续阅读一屏呈现—
头像库企业分组 + 匹配规则,为发信方匹配头像—
音乐NAS 本地曲库或 Subsonic,歌词、收藏、歌单、推荐与全屏播放NAS 音乐目录或 Subsonic(Navidrome 等)
影视NAS 片库或 Jellyfin / Emby,NFO、TMDB 补全、继续观看NAS 视频目录或 Jellyfin;TMDB Key 可选
书架TXT / EPUB / PDF / MOBI / AZW3 / FB2 阅读与进度同步—
文件分片上传、逻辑目录、在线预览与快传—
导航 / 容器 / 回收站常用站点、Docker 监控与控制、软删除恢复容器功能需要 Docker Socket

运行形态

  • 单容器:FastAPI 同时提供 API 与网页,不需要单独的 nginx 容器;默认宿主端口 18765。
  • 数据:SQLite 数据库、附件、头像、封面与密钥都在数据目录中,备份目录即备份全部。
  • 实时:消息经 SSE 推送;后端必须单 worker 运行,多 worker 会让部分连接收不到事件。
  • 用户:第一个注册的账号自动成为管理员;用户之间的消息、来源、头像、设备与播放数据相互隔离。
第一次使用? 按「部署 → 首次使用 → 接入服务」的顺序阅读;部署完成后先把管理员账号和站点信息设置好,再添加消息来源。

部署

任选一种方式:有 Docker 的机器用 Compose;不想本地构建时用官方镜像;NAS 用镜像包;需要改代码时用源码运行。所有方式共用同一个数据目录,升级时只要保留该目录即可。

Docker Compose

git clone https://github.com/limi75525/ihub.git
cd ihub
docker compose up -d --build

启动后打开 http://<主机IP>:18765。首次访问进入注册页,第一个注册的账号自动成为管理员。

  • 容器名是 ihub,端口映射为宿主 18765 到容器 8000。
  • 数据卷是 ./data:/app/data,即仓库根目录下的 data/。
  • 后端必须单 worker;不要用 --workers 扩容。
  • 经外层反向代理访问时,按下方「反向代理」设置 IHUB_TRUST_PROXY_HEADERS。

使用官方镜像

不想在本地构建时,可以直接使用官方发布的多架构镜像(amd64 / arm64):

docker pull limi75525/ihub:1.6.3

把 compose 里的 build: . 换成 image: limi75525/ihub:1.6.3,其余保持不变:

services:
  ihub:
    image: limi75525/ihub:1.6.3
    container_name: ihub
    restart: unless-stopped
    ports:
      - "18765:8000"
    volumes:
      - ./data:/app/data
  • 升级时把 1.6.3 换成新版本标签,再执行 docker compose pull && docker compose up -d。
  • GitHub Packages(GHCR)也同步发布同一镜像:ghcr.io/limi75525/ihub:latest;私有包需要先 docker login ghcr.io。
  • 官方镜像由本项目仓库发布;第三方自行构建或转发的镜像不代表本项目。

NAS 镜像包(绿联 UGOS 示例)

如果 NAS 不能或不想在本地构建,可以直接导入镜像包。下面以绿联 UGOS 为例,其他 NAS 的导入方式类似。

  1. 选择架构ARM NAS 用 arm64,x86 用 amd64。文件名形如 ihub-1.6.3-arm64.tar.gz;两个包的镜像标签相同,compose 不需要因此改动。
  2. 导入镜像方式 A:NAS 的 Docker 界面 →「镜像」→「导入」→ 选择 tar.gz,等待导入完成,列表里应出现 ihub 镜像。方式 B(SSH):
    docker load -i /volume1/你的上传目录/ihub-<版本>-arm64.tar.gz
    docker images | grep ihub
  3. 准备数据目录建一个持久化目录挂载到容器的 /app/data,例如 /volume1/docker/ihub/data。该目录存放 SQLite 数据库、邮件附件、头像、文件库文件与密钥,备份这个目录 = 备份全部数据。
  4. 写 compose 并启动按实际路径与镜像标签修改下面的示例:
    services:
      ihub:
        image: ihub:1.6.3
        pull_policy: never
        container_name: ihub
        restart: unless-stopped
        ports:
          - "18765:8000"
        environment:
          - TZ=Asia/Shanghai
          - IHUB_TIMEZONE=Asia/Shanghai
          - IHUB_TRUST_PROXY_HEADERS=true
        volumes:
          - /volume1/docker/ihub/data:/app/data
          - /volume1/Media/music:/music:ro
          - /volume1/Media/video:/video:ro
          # - /var/run/docker.sock:/var/run/docker.sock:ro
        dns:
          - 223.5.5.5
          - 119.29.29.29
    保存后在 compose 文件所在目录执行:
    docker compose up -d
    docker compose ps
  5. 访问与初始化浏览器打开 http://<NAS的IP>:18765,首次进入注册页,第一个注册的账号自动成为管理员。然后到「设置 → 接入服务」添加来源,按需开启音乐、影视或容器。
  • pull_policy: never 让 compose 只使用本地镜像,不联网拉取;如果 NAS 的 compose 版本不认这个字段,删掉该行即可。
  • 媒体目录按需挂载;不需要音乐或影视时删掉对应行。设置里的路径填容器内路径 /music / /video。
  • compose 示例里的 IHUB_TRUST_PROXY_HEADERS=true 只适用于前面还有反向代理的部署;如果 NAS 直接暴露 18765 端口、没有外层代理,删掉这一行。
  • 容器监控的 Socket 挂载默认注释;开启方式与安全边界见「容器」一节。

NAS 升级与迁移

  • 升级导入新镜像 → 把 compose 的 image: 改成新标签 → docker compose up -d。数据在 data 目录,账号与内容不受影响。
  • 从旧双容器迁移停止并移除旧的 ihub-backend / ihub-frontend 容器,数据目录不要动;用单容器 compose 指向同一个数据目录启动,账号、消息与文件库会无缝继承。
  • 端口被占用改 compose 里 "18765:8000" 左侧的宿主端口。
  • 启动报 registry timeout说明镜像还没导入,compose 正在联网拉取。先完成「导入镜像」并确认 docker images | grep ihub 能看到;使用 pull_policy: never 可避免联网。

NAS 容器 DNS 排障

如果邮箱拉取、在线封面或 TMDB 补全出现 Temporary failure in name resolution,这是容器内 DNS 解析失效,不是 iHub 的 bug。容器 DNS 默认跟随宿主机 /etc/resolv.conf;宿主机使用 systemd-resolved 本地桩(127.0.0.53)、路由器 DNS 变动或重建容器后都可能触发。

  1. 在容器内复现
    docker exec ihub cat /etc/resolv.conf
    docker exec ihub getent hosts imap.qq.com
    getent hosts imap.qq.com
    如果容器内解析失败、宿主机正常,即可确认。
  2. 加 DNS 并重建在 compose 的 ihub 服务加:
    dns:
      - 223.5.5.5
      - 119.29.29.29
    然后执行 docker compose up -d 重建容器。上面完整的 compose 示例已经默认带上这两行。

源码运行

cd ihub
python -m venv .venv
.venv/Scripts/pip install -r requirements.txt   # Linux / macOS 用 .venv/bin/pip
.venv/Scripts/python -m uvicorn app.main:app --host 0.0.0.0 --port 18765 --no-proxy-headers

前端构建产物已包含在 frontend-dist/,直接启动后端即可,不需要单独启动前端或安装 Node.js。

--no-proxy-headers 不要省略:uvicorn 默认会自行改写客户端 IP,与登录锁定、推送限流的计数口径冲突。

反向代理与 HTTPS

登录失败锁定与推送限流按客户端 IP 计数。经 Lucky / nginx / Caddy 等反向代理部署时:

  • 设 IHUB_TRUST_PROXY_HEADERS=true,让后端采信代理追加的 X-Forwarded-For。
  • 前面还有 Cloudflare 等 CDN 时,把 IHUB_TRUSTED_PROXY_HOPS 设为 2;单层反代保持 1。
  • 反代需要转发 Host、X-Forwarded-For、X-Forwarded-Proto;SSE(/api/v1/events)要关闭缓冲并放长读超时。
  • 用 GET /api/health 核对:返回的 client_ip 应该是真实客户端地址,而不是代理机内网地址。

环境变量

变量默认说明
IHUB_DATA_DIR./data数据目录:SQLite、附件、头像、封面与密钥
IHUB_SECRET_KEY自动生成JWT 与字段加密根密钥;留空则首次启动写入数据目录
IHUB_ACCESS_TOKEN_EXPIRE_DAYS7登录有效期(天)
IHUB_DEVICE_OFFLINE_MINUTES10短信 / API 来源超过该分钟数无推送则显示离线
IHUB_TIMEZONEAsia/Shanghai「今日」统计所用时区
IHUB_CORS_ORIGINS空跨域白名单,逗号分隔;同源部署留空
IHUB_TRUST_PROXY_HEADERSfalse是否采信代理传来的客户端 IP
IHUB_TRUSTED_PROXY_HOPS1可信代理层数;前面还有 CDN 时设 2
IHUB_ALLOW_PRIVATE_EMAIL_HOSTfalse允许 IMAP 连接内网邮件服务器
IHUB_DOCKER_HOSTUnix SocketDocker API 地址;可指向 docker-socket-proxy
IHUB_ENABLE_DOCSfalse是否暴露 /api/docs 与 OpenAPI 文档

数据、备份与升级

数据目录里包含 SQLite 数据库、邮件附件、上传的头像与 Logo、文件库文件、音乐/影视封面与密钥文件。备份这个目录就是备份全部数据。

  • 备份:停止容器后复制数据目录,或直接复制正在使用的目录(SQLite 建议在低峰期操作)。
  • 恢复:把目录放回原位置,保持 compose 的挂载路径不变,重新启动。
  • 升级:保留数据目录,拉取新镜像或重新构建,再 docker compose up -d。升级前仍建议备份。
  • 重置:停止服务后删除数据目录再启动,会清空所有账号与内容。

首次使用

注册管理员

打开站点后进入注册页。第一个注册的账号自动成为管理员;注册默认开放,图形验证码默认关闭,均可在「设置 → 系统」中调整。

管理员密码无法找回。 如果只是普通用户忘记密码,管理员可以在「用户」里重置;如果管理员本人也无法登录,只能删除数据目录重新初始化(数据会全部丢失),所以请务必保管好管理员账号并提前备份。

初始化站点

  1. 设置站点信息「设置 → 系统」可改站点标题、Logo、登录背景,并决定注册、验证码、回收站、消息保留期与上传上限。
  2. 添加消息来源「设置 → 接入服务」添加邮箱、短信设备或 API 来源;具体步骤见下一节。
  3. 按需开启模块音乐、影视与容器都有独立开关;未开启时入口仍然可见,页内会显示开启引导。文件库在「设置 → 文件」中管理。
  4. 检查总览「总览」会把消息、导航、快传、容器与继续阅读聚合在一屏,适合作为日常入口。

角色与数据边界

管理员可以管理用户、站点设置与容器;每个账号维护自己的消息、接入服务、头像库与设备。用户之间的消息、来源、设备、媒体收藏与播放进度按账号隔离。

回收站与保留期

  • 回收站默认开启:删除的消息、来源、头像分组与规则先进入回收站,保留 30 天,可恢复或彻底删除。关闭回收站后,删除会立即物理清除。
  • 消息保留期默认不自动清理;可在「设置 → 隐私」选择保留最近一周 / 一月 / 半年 / 一年。缩短保留期时,可以选择立即删除超出部分,或 10 分钟后自动清理(期间改回更长保留期可取消)。
  • 软删除数据到期后由后台任务物理清除,并回收附件、头像与 Logo 文件。

接入服务

消息来源分三类:邮箱(IMAP)、短信(设备签名通道)与 API 通知。短信与 API 共用同一套设备码 + HMAC 签名协议;邮箱由后端定时拉取。

邮箱(IMAP)

  1. 添加来源「设置 → 接入服务 → 添加接入服务」→ 选择「邮箱」。
  2. 选择预设QQ / Gmail / Outlook / 163 会自动填好服务器;也可以选「自定义」手填 IMAP 主机与端口。
  3. 填写授权码大多数邮箱不能直接用登录密码,需要先在邮箱端开启 IMAP 并生成授权码 / 应用专用密码。
  4. 测试并保存先点「测试连接」,通过后保存;轮询间隔默认 120 秒,可单独调整。
邮箱IMAP 服务器端口密码说明
QQ 邮箱imap.qq.com993开启 IMAP/SMTP 后使用授权码
Gmailimap.gmail.com993开启两步验证后创建应用专用密码
Outlookoutlook.office365.com993使用应用密码
163 邮箱imap.163.com993开启 IMAP 后使用授权码

iHub 以只读方式轮询 INBOX,不会改动邮箱的已读状态;按 UID 游标增量拉取,保留 HTML 正文与附件。来源卡片上的「立即拉取」用于手动触发,「重新解析」会回退游标并重拉近期邮件,应用最新的解析逻辑。

授权码是加密存储的,密钥派生自 IHUB_SECRET_KEY。如果更换了服务密钥导致旧密文无法解密,拉取会明确报错并跳过,不会拿密文去登录邮箱。

短信(Android 客户端)

  1. 在 Web 创建来源「设置 → 接入服务 → 添加接入服务」→ 选择「API」→ 消息类型选「短信」;创建后立即显示 8 位设备码与设备密钥,密钥只完整显示一次。
  2. 在 App 绑定打开 App「设置 → 短信转发 → 绑定转发设备」,填写设备码与密钥,保存并绑定。
  3. 授权通知使用权在系统设置里允许 App 读取通知;设置页状态应显示「已连接」。
  4. 发送测试App 里「发送测试消息」走同一签名链路,不产生真实消息,用来验证设备码、密钥与服务器时间。
  5. 打开转发开关发一条短信验证:消息中心应实时出现,设置页「最近转发」有记录。
授权不等于连接。 系统里已允许「通知使用权」不代表监听服务真的绑上了,应用更新后部分 ROM 不会自动重绑。设置页「通知使用权」显示「未连接」时,点整行会请求重连;仍失败时到系统设置里关闭再打开 iHub 的通知使用权,或重启手机。三星等 ROM 还需要把 iHub 加入电池优化白名单并排除深度休眠。

硬件网关与通用 API

任何能发 HTTP 请求的设备、脚本或硬件网关,都可以按设备签名协议推送。先在 Web 端取得设备码与密钥(创建 API 来源或对已有来源「绑定设备」),然后请求:

POST /api/v1/ingest/device
Content-Type: application/json
X-Device-Id:  <设备码>
X-Timestamp:  <Unix 秒>
X-Nonce:      <随机串,每次不同>
X-Signature:  hex( HMAC-SHA256(设备密钥, 签名串) )

签名串 = 设备码 + "\n" + 时间戳 + "\n" + 随机数 + "\n" + SHA256(请求体) 的 hex

通知类与短信类的请求体示例:

{"title": "资源告警 · CPU 95%", "content": "告警详情…", "sender": "monitor"}
{"from": "10086", "msg": "短信全文", "timestamp": 1730000000}
  • content / msg 必填;title、sender、extra、timestamp 可选。
  • timestamp 是消息本身的时间;不填或异常时按服务器接收时间处理。
  • 请求时间偏差需在 ±5 分钟内;nonce 不可重复,服务端会做防重放。
  • 签名取 hex 小写;body 的 SHA256 十六进制大小写都接受。
  • 鉴权失败统一返回 401 鉴权失败(不区分具体原因,防设备码枚举);来源被停用返回 403。
  • 连通性测试:POST /api/v1/ingest/device-test,与正式推送同一签名链路,不落消息。

设备与来源管理

  • 查看密钥来源行「查看密钥」需要输入当前账号密码。
  • 重置密钥重新签发后旧密钥立即失效,需要到设备端重新填写。
  • 停用/启用停用后设备推送返回 403;删除来源前必须先停用,防止误删正在收消息的来源。
  • 在线状态短信 / API 来源超过 IHUB_DEVICE_OFFLINE_MINUTES(默认 10 分钟)没有推送,会显示离线。
  • 排序来源列表支持拖拽排序,消息页与总览按该顺序展示。

音乐

音乐中心支持两种音源:NAS 本地曲库与 Subsonic(Navidrome 等兼容服务)。两者都在「设置 → 音乐」中配置。

配置音源

  • 未设置关闭音乐模块,音乐页显示开启引导。
  • NAS 本地音乐把 NAS 音乐目录挂载进容器,例如 compose 加 - /volume1/music:/music:ro,在设置里填容器内路径 /music。
  • Subsonic / Navidrome填写服务器地址、用户名与密码,先「测试连接」再保存。

保存后在设置页点「扫描音乐库」。扫描在后台线程执行,页面会轮询进度;新增或修改文件后重新扫描即可。

支持格式与扫描

扫描识别 .mp3、.flac、.wav、.m4a、.ogg、.opus、.wma、.ape。扫描会跳过未变化的文件(按修改时间与大小),只解析新增或变化的曲目;这使大曲库的重复扫描很快。

浏览与播放

  • 首页轮播(按播放次数)、歌曲推荐(每天随机 6 首)、热门单曲、随机百首与我的歌单。
  • 专辑 / 歌曲专辑网格与歌曲列表;歌曲支持按更新时间、歌手、歌名排序,按字母跳转,搜索。
  • 收藏 / 歌单红心收藏;歌单可新建、重命名、编辑描述、换封面、加曲与移除。
  • 播放底部播放条控制播放、上一首、下一首、随机/顺序、音量与队列;点封面进入全屏播放页。
  • 队列全屏播放页右侧队列可跳转曲目;歌单的「播放全部 / 随机播放」会把整列加入队列。
  • 统计播放次数、收藏、最近播放与今日听曲按用户统计。

歌词

歌词优先读取同目录同名 .lrc,其次读取音频内嵌歌词(USLT / ©lyr / LYRICS);Subsonic 源走上游歌词接口。歌词在播放条显示两行,点击歌词行可跳转到对应时间。没有歌词时显示「暂无歌词」。

说明

  • Subsonic 播放由后端代理原始流并透传 Range,支持拖动进度;不会强制转码。
  • 封面由后端代理;加载失败时回退为渐变占位。
  • 收藏与播放记录会尽量双写 Subsonic 上游;上游失败不影响本地记录。

影视

影视中心支持 NAS 本地片库与 Jellyfin / Emby 两种源,在「设置 → 影视」中配置。NAS 源可选配 TMDB Key 自动补全缺失的海报、剧照与标题 Logo。

NAS 片库

  1. 挂载目录compose 加 - /volume1/video:/video:ro,设置里填容器内路径 /video。
  2. 填入 TMDB Key(可选)在 themoviedb.org 创建 API Key;国内直连不通时填写 HTTP 代理。
  3. 扫描视频库保存后点「扫描视频库」,后台识别电影/剧集并读取 NFO 与本地图片。

支持 .mp4、.m4v、.mkv、.avi、.mov、.wmv、.webm、.mpg、.mpeg、.ts、.flv、.rmvb、.rm。

目录与命名

推荐按「电影 / 剧集」分目录,剧集放进季目录:

/video/
  电影/沙丘2 (2024)/沙丘2 (2024).mkv
  剧集/漫长的季节 (2023)/Season 1/漫长的季节 S01E01.mkv

集号识别支持 SxxExx、1x02、第x集/话、EPxx、Exx,以及「标题 - 数字」的兜底格式。电影文件末尾的数字不会被误判为集号。

NFO 与 TMDB

  • NFO 候选同名 .nfo → 目录内 movie.nfo → 向上找 tvshow.nfo → 季目录内 season.nfo / <季目录名>.nfo / seasonNN.nfo。
  • 字段标题、原名、简介、年份、评分、类型、导演、演员、时长、海报/剧照引用;剧集还有剧名、季简介等。NFO 非空字段才覆盖文件名解析结果。
  • TMDB 编号电影读 <tmdbid>,剧集读 tvshow.nfo 的编号;没有编号时会按标题 + 年份尝试自动匹配(宁缺毋滥,歧义时放弃)。
  • 图片优先级本地图片永远优先:NFO 引用 → 同目录图片 → 分集向剧集目录回探 → 在线缓存。在线只下载缺失的图,不写回媒体目录。
  • 增量视频或 NFO 变化(修改时间/大小)会触发该条目重新解析;重扫不会重新查询已经落库的 TMDB 编号。

Jellyfin

填写 Jellyfin 地址、用户名与密码,先测试连接。Emby 大体兼容但未逐一验证。播放经后端代理原文件直出并透传 Range;观影进度会尽量双写上游,上游失败不影响本地记录。

浏览与播放

  • 首页继续观看与最近添加;「最近添加」按片聚合,剧集按剧名合并。
  • 电影 / 剧集电影海报网格分页;剧集先选剧,再进分集列表。
  • 详情宽幅剧照页头(多张自动轮播)、标题 Logo、评分/年份/时长/类型、简介、导演与演员、播放按钮。
  • 续播观看超过 30 秒且不到 95% 才进入继续观看;剧集的播放按钮会记住上次看到哪一集。
  • 播放器全屏播放、每 10 秒上报进度、关闭时收尾;再次打开可续播。

书架与文件

书架

支持 TXT、EPUB、PDF、MOBI、AZW3、FB2。在书架页上传后会自动解析书名、作者、封面与章节。

  • 阅读器支持滚动/双栏、四档字号、三档行距与四种主题(纸白 / 羊皮 / 护眼 / 夜间)。
  • 进度阅读位置按账号同步;再次打开从上次位置继续。
  • PDF使用浏览器内置查看器;如果浏览器不支持内嵌 PDF,可在新窗口打开。
  • 管理书架列表可删除书籍;封面缺失时显示占位。

文件库

管理员在「设置 → 文件」中管理文件库;普通用户可以从总览的快传卡收发文件。文件库是逻辑目录:左侧目录树、右侧文件网格,物理文件仍然平铺在数据目录的 transfer/<用户>/ 下。

  • 上传支持拖拽、粘贴与多选;大文件按 4MB 分片上传,绕开反代请求体限制,失败只需重传单片。
  • 单文件上限默认 512MB,可在「设置 → 系统」调整为 1–2048MB。
  • 目录可新建子目录、重命名、删除空目录;文件可移动到其他目录,支持批量选择、全选与框选。
  • 搜索搜索覆盖全部目录,结果会显示文件所在目录。
  • 预览图片、视频、PDF、Word、Markdown 与常见代码文件可在线预览。
  • 来源标记文件库上传标记为 library,快传上传标记为 share;总览快传卡只显示快传文件。

快传

总览右侧的快传卡用于在电脑、手机与 NAS 之间中转文件。上传后可在另一端下载;文件按用户隔离,需要登录才能访问。设置 → 隐私里的「快传隐私」开启后,快传卡内容会在总览上模糊显示,悬停才显现。

容器

容器监控与控制是可选功能,默认关闭。开启后可以查看本机 Docker 容器的状态、端口、资源占用与日志,并可选执行启停、重启、删除与拉取镜像。它需要 iHub 能访问 Docker API,有两种授权方式:直接挂载 Socket,或经过 docker-socket-proxy。

先理解两个权限

  • 监控(只读)容器列表、状态、镜像、端口、CPU/内存、运行时长、日志、磁盘占用与容器事件。
  • 控制(可写)启停、重启、删除容器与拉取镜像。写操作需要管理员 + 监控 + 控制三重校验,并逐条记录审计日志。
  • 「设置 → 系统」里的「容器监控与控制」是单个界面开关,会同时写入监控与控制两项;关闭时即使已挂载 Socket,后端也不会访问 Docker。后端仍保留两个独立设置项,API 可以只开监控做纯只读部署。
  • 授权只是前提,开关默认关闭;新部署或刚挂载 Socket 后,需要到设置里手动打开一次。

方式一:直接挂载 Docker Socket

最简单的方式,适合单机、完全信任 iHub 的部署。Docker Socket 约等于宿主机最高权限,开启前请确认 iHub 只在内网或可信网络中访问。

  1. 给 ihub 服务挂载 Socket在 compose 的 ihub 服务 volumes 中追加一行:
        volumes:
          - ./data:/app/data
          - /var/run/docker.sock:/var/run/docker.sock
    如果原来已经挂了其他目录,保留它们,只追加 Socket 这一行。
  2. 重建容器挂载和 IHUB_DOCKER_HOST 都是启动时读取的,改完 compose 必须重建 iHub,而不是只刷新页面:
    docker compose up -d --force-recreate ihub
  3. 在 iHub 内开启「设置 → 系统 → 容器监控与控制」打开开关,然后进入侧边栏「容器」页验证。

方式二:docker-socket-proxy(推荐)

tecnativa/docker-socket-proxy 会在 Docker Socket 前面加一层 HTTP 代理。iHub 只连接代理,不直接接触 Socket;代理按接口白名单决定哪些 Docker API 可用,默认可以做成只读。代理不需要映射端口到宿主机,只让同一 compose 网络内的 iHub 访问。

  1. 新增代理服务在同一个 compose 文件里加上代理,并给 iHub 设置 IHUB_DOCKER_HOST。完整示例:
    services:
      docker-socket-proxy:
        image: tecnativa/docker-socket-proxy
        container_name: docker-socket-proxy
        restart: unless-stopped
        privileged: true          # SELinux / AppArmor 场景通常需要
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock:ro
        environment:
          - CONTAINERS=1   # 容器列表、详情、日志、资源占用
          - SYSTEM=1       # 磁盘占用 /system/df
          # events、ping、version 默认放行
          # POST / DELETE 默认 0 = 只读代理,勿随意开启
        # 不要配置 ports 映射到宿主机:只允许 compose 内网访问
    
      ihub:
        image: ihub:1.6.3
        # 保留原来的 data、音乐、影视挂载
        environment:
          - IHUB_DOCKER_HOST=tcp://docker-socket-proxy:2375
        # 不要再挂 /var/run/docker.sock
    关键是两点:ihub 不再挂 Socket;IHUB_DOCKER_HOST 指向代理的服务名与端口 2375。两个服务在同一个 compose 项目里会自动加入同一网络。
  2. 重建并确认执行:
    docker compose up -d
    docker compose ps
    ihub 与 docker-socket-proxy 都应为 running。修改了 IHUB_DOCKER_HOST 后必须重建 iHub 容器(--force-recreate),只重启进程不会重新读取环境变量。
  3. 代理镜像拉取失败?NAS 无法访问 Docker Hub 时,先在能联网的电脑上拉取,再导出并导入 NAS:
    docker pull tecnativa/docker-socket-proxy
    docker save tecnativa/docker-socket-proxy | gzip > docker-socket-proxy.tar.gz
    把 tar.gz 导入 NAS 的 Docker 镜像列表,再启动 compose。
  4. 在 iHub 内开启「设置 → 系统 → 容器监控与控制」打开开关;只读代理下「容器」页只显示查看能力,不显示启停/删除按钮。

只读、可写与代理白名单

用途代理环境变量iHub 能做什么
只读监控CONTAINERS=1、SYSTEM=1;POST / DELETE 保持默认 0列表、状态、日志、CPU/内存、磁盘占用;不能启停或删除
可写(粗粒度)POST=1、DELETE=1启停、重启、删除、拉取镜像;POST=1 会放开所有 POST 接口,风险最大
可写(细化)ALLOW_START=1、ALLOW_STOP=1、ALLOW_RESTARTS=1、DELETE=1只放行启停/重启/删除;是否能覆盖拉镜像取决于代理版本,需实测

拉取镜像走 Docker 的 POST /images/create,只读代理会拒绝;如果确实需要在 iHub 内拉镜像,必须放行 POST=1(或在代理版本支持时放行对应接口)。ALLOW_START / ALLOW_STOP / ALLOW_RESTARTS 是更细的开关,但不同代理版本支持情况不完全一致,配置后应到容器页实际验证。

启用后的功能

  • 列表容器名称、状态、镜像、端口映射、CPU/内存占用与已运行时长;卡片点击打开日志抽屉。
  • 日志自动剥离 ANSI 颜色控制符,网页端可读;长日志在抽屉内滚动。
  • 控制启动、停止、重启、删除、拉取镜像。删除需要输入容器名二次确认,且不带 -v(不删数据卷)。
  • 拉取只执行镜像拉取,不自动重建容器;拉取后到 NAS 或 compose 中重建。
  • 审计所有写操作都会记录审计日志,可在后端日志中核对。

安全边界

Docker Socket 约等于宿主机 root。 直接挂载 Socket 等于把最高权限交给 iHub。更稳妥的做法是用 socket-proxy,并且只放行确实需要的接口;POST=1 会放宽只读约束,开启前请理解风险。
  • 代理的 Socket 挂载使用 :ro;不要给代理映射宿主机端口,避免暴露 2375。
  • iHub 只在内网或可信网络中使用,管理员账号使用强密码;不要把容器控制权限开放给普通用户。
  • 默认关闭、三重校验与审计日志都是防线,不是替代品;不需要容器功能时不要挂载 Socket。
  • 删除容器不删数据卷;需要清理卷或镜像时,到宿主机手动操作,不要把这类能力扩展到 iHub。

排障

  • 容器页 503监控开关未开,或 Docker 不可达。先检查「设置 → 系统」开关,再 docker compose ps 看代理/iHub 是否 running;使用代理时确认 IHUB_DOCKER_HOST 已写入并重建过 iHub。
  • 容器页 403当前账号不是管理员,或写操作所需的控制开关未开。
  • 代理连不上确认代理与 iHub 在同一个 compose 网络、服务名是 docker-socket-proxy、端口是 2375;看 docker compose logs docker-socket-proxy 是否有权限或 Socket 错误。
  • Permission denied代理读取不到 Socket。确认挂载的是 /var/run/docker.sock;SELinux/AppArmor 环境按代理说明启用 privileged: true。
  • 启停/删除按钮不可用只读代理只放行读取接口;按上面的白名单表放行对应写接口后重建代理。

如果还不是很了解,可以继续阅读 docker-socket-proxy 的官方文档:tecnativa/docker-socket-proxy。

设置与用户

「设置」按栏目组织,管理员能看到系统、文件、影视、音乐与用户等栏目,普通用户主要使用隐私、接入服务与头像库。

栏目主要内容
系统站点标题与 Logo、登录背景、开放注册、登录/注册验证码、回收站、消息保留期、头像与文件上传上限、容器监控与控制
隐私记录最近浏览、清除浏览记录、消息保留期清理;快传隐私模糊
接入服务邮箱、短信设备与 API 来源的增删改、绑定设备、测试连接、排序
头像库企业分组、匹配规则、默认/精确头像、从文件库选图、ZIP 导入导出
文件文件库目录树、上传、预览、移动、批量操作与删除
影视 / 音乐模块开关、音源、目录、扫描、TMDB / Subsonic / Jellyfin 配置
用户用户列表、角色、昵称、头像、登录账号、重置密码、删除用户
关于版本、更新日志(连点 Logo 6 次弹出)

用户管理

管理员可以在「用户」里修改昵称、头像、登录账号与角色,也可以重置密码或删除用户。删除用户会清理其消息、来源、设备、文件、音乐收藏与影视进度等数据;操作前请确认。

头像库

头像库按「企业分组 + 匹配规则」组织:一个企业有默认头像,成员规则保存号码、签名、邮箱账户或精确头像。匹配顺序大致为:号码/邮箱精确 → 签名精确 → 签名前缀(最长企业名优先)→ 邮箱 @ 域名 → 分组名兜底。

  • 头像来源:本地上传、在线地址(输入域名会自动补全 https://a.favicon.im/ 前缀)或从文件库选择。
  • 导入/导出为 ZIP:包含 manifest.json 与 images/,支持 PNG / JPG / JPEG / GIF / WebP 等位图;也兼容旧的 JSON 清单。
  • 删除企业分组会级联删除成员规则,进入回收站后可整组恢复。

常见问题

反向代理后,所有人都共用一个限流计数?

把 IHUB_TRUST_PROXY_HEADERS 设为 true,按代理层数设置 IHUB_TRUSTED_PROXY_HOPS(单层 1,前面还有 CDN 时 2)。用 GET /api/health 验证返回的 client_ip 是否为真实客户端地址。

登录失败几次后被锁定了?

同一用户名失败 5 次,或同一 IP 失败 20 次,会锁定 15 分钟。反向代理未正确配置时,所有外部访问可能共用一个 IP 计数,先按上一条检查代理头。

邮箱连不上或拉不到新邮件?

先确认邮箱端已开启 IMAP;多数邮箱要用授权码而不是登录密码。用来源编辑里的「测试连接」排查,错误信息会区分认证失败与网络失败。若只在 NAS 容器内失败并出现 Temporary failure in name resolution,是容器 DNS 问题,见下一条。

NAS 容器里 DNS 解析失败怎么办?

这是容器内 DNS 失效,不是 iHub 的 bug。给 compose 的 ihub 服务加 dns: [223.5.5.5, 119.29.29.29] 后重建容器;可用 docker exec ihub getent hosts imap.qq.com 在容器内复现与验证。

短信推送一直返回 401 或 403?

401 表示签名校验失败:核对设备码与设备密钥是否与 Web 端一致(复制不要带空格)、设备时间是否准确、nonce 是否重复。403 表示设备所属来源被停用,先到接入服务里启用。重置过密钥后,设备端必须重新填写。

Android 显示已授权,但状态是「未连接」?

授权和实际绑定时两回事。点设置页「通知使用权」整行请求重连;仍不行就到系统设置里关闭再打开 iHub 的通知使用权,或重启手机。把 iHub 加入电池优化白名单、排除深度休眠,能避免服务被 ROM 冻结。

音乐扫描不到歌曲?

检查 NAS 目录是否已挂载进容器、设置里的路径是否是容器内路径(如 /music)、文件格式是否在支持列表内,以及容器用户是否有读取权限。保存后重新扫描,并在扫描状态里看进度与结果。

Subsonic 播放或封面报 401?

先「测试连接」确认地址、用户名与密码;上游修改密码或吊销令牌后,需要重新保存配置。播放走服务端代理,浏览器不直接接触 Subsonic 凭据。

歌词不显示?

确认音频同目录有同名 .lrc,或音频内嵌了歌词标签;Subsonic 源需要上游支持歌词接口。歌词在播放条显示两行,点击行可跳转。

影视没有海报或剧照?

NAS 源优先使用本地图片与 NFO 引用;没有本地图且配置了 TMDB Key 时才会在线补全。检查 Key、网络代理与 NFO 编号;保存后重新扫描。详情页发现缺图时也会尝试懒补一次。

改了 NFO,但详情没更新?

重新扫描视频库即可。NFO 的修改时间或大小变化会触发该条目重新解析;如果 NFO 没有变化,扫描会跳过。改完 NFO 后不要只刷新页面,先重扫。

Jellyfin 报 401 或 502?

401 多为地址、用户名或密码不对,或上游令牌被吊销;502 多为网络不可达或上游服务异常。先「测试连接」,再检查 iHub 容器到 Jellyfin 的网络。

容器页 503 或 403?

503 表示监控开关未开或 Docker 不可达:检查 compose 是否挂载 Socket / 代理地址是否正确,以及「设置 → 系统」的开关。403 表示不是管理员,或写操作所需的控制开关未开。

忘记管理员密码怎么办?

管理员可以在「用户」里重置其他账号的密码。如果管理员本人无法登录,目前没有找回入口,只能删除数据目录重新初始化(会清空所有数据)。请提前备份数据目录并保管好管理员账号。

怎么备份和迁移?

备份数据目录(默认 ./data)即可,里面包含数据库、附件、头像、文件库与密钥。迁移时把目录放到新机器的同一挂载路径,保持 compose 的数据卷不变,再启动服务。