iHub Docs · 1.6.x
使用文档
从部署、首次初始化,到消息接入、音乐、影视、书架、文件与容器。内容按 iHub 1.6.x 的实际界面与接口整理;遇到问题先看最后的「常见问题」。
概览
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 的导入方式类似。
- 选择架构ARM NAS 用
arm64,x86 用amd64。文件名形如ihub-1.6.3-arm64.tar.gz;两个包的镜像标签相同,compose 不需要因此改动。 - 导入镜像方式 A:NAS 的 Docker 界面 →「镜像」→「导入」→ 选择 tar.gz,等待导入完成,列表里应出现
ihub镜像。方式 B(SSH):docker load -i /volume1/你的上传目录/ihub-<版本>-arm64.tar.gz docker images | grep ihub - 准备数据目录建一个持久化目录挂载到容器的
/app/data,例如/volume1/docker/ihub/data。该目录存放 SQLite 数据库、邮件附件、头像、文件库文件与密钥,备份这个目录 = 备份全部数据。 - 写 compose 并启动按实际路径与镜像标签修改下面的示例:
保存后在 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.29docker compose up -d docker compose ps - 访问与初始化浏览器打开
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 变动或重建容器后都可能触发。
- 在容器内复现
如果容器内解析失败、宿主机正常,即可确认。docker exec ihub cat /etc/resolv.conf docker exec ihub getent hosts imap.qq.com getent hosts imap.qq.com - 加 DNS 并重建在 compose 的
ihub服务加:
然后执行dns: - 223.5.5.5 - 119.29.29.29docker 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_DAYS | 7 | 登录有效期(天) |
IHUB_DEVICE_OFFLINE_MINUTES | 10 | 短信 / API 来源超过该分钟数无推送则显示离线 |
IHUB_TIMEZONE | Asia/Shanghai | 「今日」统计所用时区 |
IHUB_CORS_ORIGINS | 空 | 跨域白名单,逗号分隔;同源部署留空 |
IHUB_TRUST_PROXY_HEADERS | false | 是否采信代理传来的客户端 IP |
IHUB_TRUSTED_PROXY_HOPS | 1 | 可信代理层数;前面还有 CDN 时设 2 |
IHUB_ALLOW_PRIVATE_EMAIL_HOST | false | 允许 IMAP 连接内网邮件服务器 |
IHUB_DOCKER_HOST | Unix Socket | Docker API 地址;可指向 docker-socket-proxy |
IHUB_ENABLE_DOCS | false | 是否暴露 /api/docs 与 OpenAPI 文档 |
数据、备份与升级
数据目录里包含 SQLite 数据库、邮件附件、上传的头像与 Logo、文件库文件、音乐/影视封面与密钥文件。备份这个目录就是备份全部数据。
- 备份:停止容器后复制数据目录,或直接复制正在使用的目录(SQLite 建议在低峰期操作)。
- 恢复:把目录放回原位置,保持 compose 的挂载路径不变,重新启动。
- 升级:保留数据目录,拉取新镜像或重新构建,再
docker compose up -d。升级前仍建议备份。 - 重置:停止服务后删除数据目录再启动,会清空所有账号与内容。
首次使用
注册管理员
打开站点后进入注册页。第一个注册的账号自动成为管理员;注册默认开放,图形验证码默认关闭,均可在「设置 → 系统」中调整。
初始化站点
- 设置站点信息「设置 → 系统」可改站点标题、Logo、登录背景,并决定注册、验证码、回收站、消息保留期与上传上限。
- 添加消息来源「设置 → 接入服务」添加邮箱、短信设备或 API 来源;具体步骤见下一节。
- 按需开启模块音乐、影视与容器都有独立开关;未开启时入口仍然可见,页内会显示开启引导。文件库在「设置 → 文件」中管理。
- 检查总览「总览」会把消息、导航、快传、容器与继续阅读聚合在一屏,适合作为日常入口。
角色与数据边界
管理员可以管理用户、站点设置与容器;每个账号维护自己的消息、接入服务、头像库与设备。用户之间的消息、来源、设备、媒体收藏与播放进度按账号隔离。
回收站与保留期
- 回收站默认开启:删除的消息、来源、头像分组与规则先进入回收站,保留 30 天,可恢复或彻底删除。关闭回收站后,删除会立即物理清除。
- 消息保留期默认不自动清理;可在「设置 → 隐私」选择保留最近一周 / 一月 / 半年 / 一年。缩短保留期时,可以选择立即删除超出部分,或 10 分钟后自动清理(期间改回更长保留期可取消)。
- 软删除数据到期后由后台任务物理清除,并回收附件、头像与 Logo 文件。
接入服务
消息来源分三类:邮箱(IMAP)、短信(设备签名通道)与 API 通知。短信与 API 共用同一套设备码 + HMAC 签名协议;邮箱由后端定时拉取。
邮箱(IMAP)
- 添加来源「设置 → 接入服务 → 添加接入服务」→ 选择「邮箱」。
- 选择预设QQ / Gmail / Outlook / 163 会自动填好服务器;也可以选「自定义」手填 IMAP 主机与端口。
- 填写授权码大多数邮箱不能直接用登录密码,需要先在邮箱端开启 IMAP 并生成授权码 / 应用专用密码。
- 测试并保存先点「测试连接」,通过后保存;轮询间隔默认 120 秒,可单独调整。
| 邮箱 | IMAP 服务器 | 端口 | 密码说明 |
|---|---|---|---|
| QQ 邮箱 | imap.qq.com | 993 | 开启 IMAP/SMTP 后使用授权码 |
| Gmail | imap.gmail.com | 993 | 开启两步验证后创建应用专用密码 |
| Outlook | outlook.office365.com | 993 | 使用应用密码 |
| 163 邮箱 | imap.163.com | 993 | 开启 IMAP 后使用授权码 |
iHub 以只读方式轮询 INBOX,不会改动邮箱的已读状态;按 UID 游标增量拉取,保留 HTML 正文与附件。来源卡片上的「立即拉取」用于手动触发,「重新解析」会回退游标并重拉近期邮件,应用最新的解析逻辑。
IHUB_SECRET_KEY。如果更换了服务密钥导致旧密文无法解密,拉取会明确报错并跳过,不会拿密文去登录邮箱。短信(Android 客户端)
- 在 Web 创建来源「设置 → 接入服务 → 添加接入服务」→ 选择「API」→ 消息类型选「短信」;创建后立即显示 8 位设备码与设备密钥,密钥只完整显示一次。
- 在 App 绑定打开 App「设置 → 短信转发 → 绑定转发设备」,填写设备码与密钥,保存并绑定。
- 授权通知使用权在系统设置里允许 App 读取通知;设置页状态应显示「已连接」。
- 发送测试App 里「发送测试消息」走同一签名链路,不产生真实消息,用来验证设备码、密钥与服务器时间。
- 打开转发开关发一条短信验证:消息中心应实时出现,设置页「最近转发」有记录。
硬件网关与通用 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 片库
- 挂载目录compose 加
- /volume1/video:/video:ro,设置里填容器内路径/video。 - 填入 TMDB Key(可选)在 themoviedb.org 创建 API Key;国内直连不通时填写 HTTP 代理。
- 扫描视频库保存后点「扫描视频库」,后台识别电影/剧集并读取 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 只在内网或可信网络中访问。
- 给 ihub 服务挂载 Socket在 compose 的
ihub服务volumes中追加一行:
如果原来已经挂了其他目录,保留它们,只追加 Socket 这一行。volumes: - ./data:/app/data - /var/run/docker.sock:/var/run/docker.sock - 重建容器挂载和
IHUB_DOCKER_HOST都是启动时读取的,改完 compose 必须重建 iHub,而不是只刷新页面:docker compose up -d --force-recreate ihub - 在 iHub 内开启「设置 → 系统 → 容器监控与控制」打开开关,然后进入侧边栏「容器」页验证。
方式二:docker-socket-proxy(推荐)
tecnativa/docker-socket-proxy 会在 Docker Socket 前面加一层 HTTP 代理。iHub 只连接代理,不直接接触 Socket;代理按接口白名单决定哪些 Docker API 可用,默认可以做成只读。代理不需要映射端口到宿主机,只让同一 compose 网络内的 iHub 访问。
- 新增代理服务在同一个 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.sockihub不再挂 Socket;IHUB_DOCKER_HOST指向代理的服务名与端口2375。两个服务在同一个 compose 项目里会自动加入同一网络。 - 重建并确认执行:
docker compose up -d docker compose psihub与docker-socket-proxy都应为 running。修改了IHUB_DOCKER_HOST后必须重建 iHub 容器(--force-recreate),只重启进程不会重新读取环境变量。 - 代理镜像拉取失败?NAS 无法访问 Docker Hub 时,先在能联网的电脑上拉取,再导出并导入 NAS:
把 tar.gz 导入 NAS 的 Docker 镜像列表,再启动 compose。docker pull tecnativa/docker-socket-proxy docker save tecnativa/docker-socket-proxy | gzip > docker-socket-proxy.tar.gz - 在 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 中重建。
- 审计所有写操作都会记录审计日志,可在后端日志中核对。
安全边界
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 的数据卷不变,再启动服务。