让每一个 Unraid Docker 容器都有整齐、稳定、可回滚的图标。
中文主文档 · English supplementary documentation · Docker Compose 部署 · 升级与回滚 · 安全说明
真实 Unraid 环境中的桌面端容器图标总览
Important
**这是一个纯 AI 项目。**作者本人完全不会编程,只是有点强迫症,看到 Unraid 里有些容器没有图标就很难受,于是靠 AI 一点一点把这个工具做了出来。
如果它刚好也解决了你的问题,欢迎使用、反馈和参与改进;但请理解,项目的代码、测试、文档和发布流程均由 AI 协助完成。
通过轻量级、自托管 Web 管理界面批量管理当前已部署 Unraid Docker 容器的图标。保存图标时只更新模板、图库和缓存;点击同步到 Unraid后,工具会为所选容器持久化 net.unraid.docker.icon,并只重建这些容器,使 Docker Manager 与 Compose Manager 都使用新图标。
Warning
本服务只能放在可信局域网。它需要 Docker socket;启用 VM 图标时还需要读写 libvirt socket,该 socket 等同完整虚拟机管理权限。v0.1.22 起生产启动必须设置 ADMIN_TOKEN,管理 API 需要登录与同源安全校验。不要把服务端口或反向代理暴露到公网。
- 容器卡片支持右键菜单,可更换图标、修复图标同步,并通过确认弹窗启动或重启容器。
- 修复镜像更新或容器重建后 Unraid 图标掉失:先重建目标容器,再写入持久与 RAM 图标缓存。
- 管理器会保留显示已保存的模板图标,同时明确标记运行标签是否需要重新同步。
- 缩小图库复选框、元数据与操作按钮;XML 安装模板改用
latest。
完整记录见 CHANGELOG.md,安装包见 v0.1.26 Release。
启用 VM 图标时请挂载宿主机 /var/run/libvirt 整个运行目录到容器同一路径,不要单独映射 libvirt-sock 文件。Unraid 重启时 libvirt 可能晚于 Docker 创建 socket;父目录挂载能让新 socket 自动出现在容器内。
- 以当前已部署 Docker 容器为列表来源,而非历史模板文件。
- 直接显示 Unraid 当前 RAM/持久缓存或明确
net.unraid.docker.icon标签中的实际图标,包括图标不在用户模板内的 Compose 容器。本地标签路径通过配置的 Unraid WebGUI 地址显示,不需要挂载 Compose 项目目录。 - 每个当前容器都可设置图标:已有匹配模板时更新模板;没有模板时,自动生成带清晰标记和审计记录的专用图标元数据模板,匹配实际容器名与镜像,并避免与现有
my-*.xml文件冲突。 - 保存阶段不重建容器;用户明确点击同步后,普通容器会仅重建所选容器,Compose Manager 容器还会原子更新对应项目
docker-compose.override.yml中所选服务的图标标签,再仅重建该服务。其他服务、数据卷和 Compose 主文件不受影响;失败时自动恢复原容器与 override。 - 支持搜索、多选,并可直接点击任意容器卡片打开单容器图标编辑器。
- 右键容器可更换或修复图标;运行中容器可确认后重启,停止或已创建容器可确认后启动,结果通过页面通知显示。
- 每次上传或实际使用外部图标 URL 时,都会先下载、校验、规范化为稳定 PNG,按内容去重后持久保存到图标图库;下载失败时不会修改模板。
- 图标图库支持自定义分组、分类筛选和移动分类,并可复制宿主机/容器根目录;每张图标还可复制自身完整 HTTP 地址、完整宿主机文件路径和完整容器文件路径。
- 图标与壁纸图库支持批量上传、浏览器选择文件夹扫描、批量删除和显示名称重命名;新上传素材使用短文件名保存,已使用的旧文件名继续兼容。
- 可从明确的 Docker Compose/容器标签及本地镜像元数据发现图标候选;选择候选后同样会先安全下载入库,不读取 Compose 文件或拉取镜像。
- 独立壁纸图库支持上传、URL 下载、手动分组与设为背景;左下角透明度滑块从
0%(完全显示壁纸、主色块透明)到100%(主题纯色、壁纸不可见),设置随/config持久保存。 - 可选的虚拟机图标页通过 libvirt metadata 修改
vmtemplate@icon,支持 URL、上传和图库选择,不重启虚拟机。 - 每次修改都会创建带时间戳的模板备份与审计记录;可单项回滚。回滚只会删除本工具创建且仍匹配的生成模板。
- 图标图库中的 PNG 会直接写入目标容器的 RAM 与持久图标缓存。两份旧缓存都会进入审计备份,可原样回滚。
- 通过
UNRAID_DOCKER_URL提供同步到 Unraid 并打开 Docker 页面操作。 - 提供参考 Docker Copilot 信息层级的管理界面,并在“关于”页展示可选的维护者支持二维码。
程序通过 socket 读取正在运行或已部署的 Docker 容器名、镜像和状态,再寻找容器 <Name> 与镜像 <Repository> 都匹配的 Unraid 模板。历史遗留模板不会出现在列表中。运行容器标签不可原地修改,因此保存后必须点击同步;Compose Manager 项目会把新标签持久保存到 override,普通 Docker Manager 容器则继续以 Unraid 模板作为未来更新来源。
docker pull waning/unraid-icon-manager:latest在 Unraid Docker 标签页中新建容器,并配置以下映射:
| Unraid 主机路径 | 容器路径 | 权限 | 用途 |
|---|---|---|---|
/mnt/user/appdata/unraid-icon-manager |
/config |
读写 | 数据库、图标与壁纸图库、审计记录与备份 |
/boot/config/plugins/dockerMan/templates-user |
/unraid/templates-user |
读写 | 现有与本工具生成的 Docker Manager 图标元数据 |
/var/lib/docker/unraid/images |
/unraid/icon-cache |
读写 | 只备份和更新发生变更的持久 Docker Manager 图标文件 |
/usr/local/emhttp/state/plugins/dynamix.docker.manager/images |
/unraid/icon-cache-ram |
读写 | 只备份和更新发生变更的 RAM 图标文件 |
/mnt/user/docker |
/unraid/compose-projects |
读写 | 仅原子更新所选 Compose Manager 服务的 docker-compose.override.yml 图标标签 |
/var/run/docker.sock |
/var/run/docker.sock |
只读挂载 | 读取容器信息;显式同步时只重建所选容器。:ro 不限制 Docker API 权限 |
/usr/local/emhttp/plugins/dynamix.vm.manager/templates/images |
/unraid/vm-icons |
读写(可选) | VM Manager 图标文件 |
/var/run/libvirt |
/var/run/libvirt |
读写(可选) | 挂载 libvirt 运行目录,让 socket 在 Unraid 重启后重新创建;等同完整 VM 管理权限 |
将 TCP 8787 映射到空闲主机端口。然后在高级变量中填写实际主机侧 URL:
| 变量 | 示例 | 用途 |
|---|---|---|
PUBLIC_BASE_URL |
http://192.168.1.10:8787 |
Unraid 主机通过该 HTTP(S) URL 下载上传的 PNG 图标;必须使用映射后的主机端口,并能被 Unraid 主机访问。 |
UNRAID_DOCKER_URL |
http://192.168.1.10:5000/Docker |
点击刷新 Docker 页面时打开的地址;如果 WebGUI 使用其他端口,请一并修改。 |
UNRAID_VM_URL |
http://192.168.1.10:5000/VMs |
修改 VM 图标后打开的 Unraid VM 页面。 |
ICON_HOST_ROOT |
/mnt/user/appdata/unraid-icon-manager/icons |
对应 /config/icons 的主机路径;移动 appdata 时一同修改。 |
COMPOSE_HOST_ROOT |
/mnt/user/docker |
Compose Manager 的 PROJECTS_FOLDER;用于写回所选服务的 override。 |
ADMIN_TOKEN |
随机 24 位以上字符串 | 必填。首次打开 Web UI 时输入;不写入数据库和日志。可用 openssl rand -base64 36 生成。 |
TRUSTED_NETWORKS |
192.168.0.0/16 等 RFC1918 网段 |
建议缩小为你的 LAN,例如 192.168.2.0/24;不在范围内的连接会被拒绝。 |
启动后访问 http://你的_UNRAID_IP:8787。也可将 unraid/template.xml 复制到 /boot/config/plugins/dockerMan/templates-user/,在 Add Container 中选择 unraid-icon-manager,并在应用前填写两个 URL 变量。
下面是可以直接复制使用的完整配置,与仓库中的 docker-compose.yml 保持一致。它完全不依赖 .env。保存为 docker-compose.yml 后,把三处 192.168.1.10 改成你的 Unraid IP:
services:
unraid-icon-manager:
image: waning/unraid-icon-manager:v0.1.26
container_name: unraid-icon-manager
ports:
- "8787:8787"
environment:
- TZ=Asia/Shanghai
# 必填:改成你自己的随机值(至少 24 位),不要保留 CHANGE_ME。
- ADMIN_TOKEN=CHANGE_ME_USE_A_RANDOM_32_CHARACTER_TOKEN
# 可收紧为你的实际 LAN,例如 192.168.2.0/24。
- TRUSTED_NETWORKS=127.0.0.1/32,::1/128,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
- ICON_HOST_ROOT=/mnt/user/appdata/unraid-icon-manager/icons
- WALLPAPER_HOST_ROOT=/mnt/user/appdata/unraid-icon-manager/wallpapers
- ICON_CACHE_DIR=/unraid/icon-cache
- ICON_CACHE_RAM_DIR=/unraid/icon-cache-ram
- COMPOSE_PROJECTS_DIR=/unraid/compose-projects
- COMPOSE_HOST_ROOT=/mnt/user/docker
- MAX_UPLOAD_BYTES=5242880
- MAX_WALLPAPER_BYTES=31457280
- MAX_ICON_GALLERY_BYTES=524288000
- MAX_WALLPAPER_GALLERY_BYTES=2147483648
- MAX_MUTATION_QUEUE=20
# 部署前把 192.168.1.10 改成你的 Unraid IP;不能填写 localhost。
- PUBLIC_BASE_URL=http://192.168.1.10:8787
# 如果 Unraid WebGUI 不是 5000 端口,请直接修改这里。
- UNRAID_DOCKER_URL=http://192.168.1.10:5000/Docker
- UNRAID_VM_URL=http://192.168.1.10:5000/VMs
- VM_ICONS_DIR=/unraid/vm-icons
- LIBVIRT_URI=qemu+unix:///system?socket=/var/run/libvirt/libvirt-sock
volumes:
# 数据库、图库、审计记录和备份。
- /mnt/user/appdata/unraid-icon-manager:/config
# Unraid Docker Manager 用户模板。
- /boot/config/plugins/dockerMan/templates-user:/unraid/templates-user
# Unraid 持久图标缓存与内存图标缓存。
- /var/lib/docker/unraid/images:/unraid/icon-cache
- /usr/local/emhttp/state/plugins/dynamix.docker.manager/images:/unraid/icon-cache-ram
# Compose Manager 项目:只用于持久更新所选服务的图标标签。
- /mnt/user/docker:/unraid/compose-projects
# 读取容器信息;显式同步时会通过 Docker API 重建所选容器。
- /var/run/docker.sock:/var/run/docker.sock:ro
# 可选 VM 图标功能;挂载整个运行目录,避免重启竞态把 socket 建成目录。
# 仅在 Unraid VM Manager 已启用时取消下面两行注释;运行目录具有完整 VM 管理权限。
# - /usr/local/emhttp/plugins/dynamix.vm.manager/templates/images:/unraid/vm-icons
# - /var/run/libvirt:/var/run/libvirt
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
read_only: true
tmpfs:
- /tmp:rw,noexec,nosuid,nodev,size=64m
pids_limit: 256
mem_limit: 512m
cpus: 1.0
networks:
- icon-manager
restart: unless-stopped
networks:
icon-manager:
driver: bridge所有参数都直接写在 Compose 中,不需要创建其他文件。确认 IP、端口和路径后,先检查配置,再启动:
docker compose config
docker compose pull
docker compose up -d启动完成后访问 http://你的_UNRAID_IP:8787。建议同时检查健康状态:
curl http://你的_UNRAID_IP:8787/api/health正常结果为 { "ok": true, "version": "0.1.26" }。健康检查不再泄露宿主机挂载状态;请登录 Web UI 确认 Docker、模板与 VM 连接状态。
| 字段 | 当前设置 | 含义与注意事项 |
|---|---|---|
services.unraid-icon-manager |
服务名 | Compose 内部服务标识;升级命令可以只操作它,避免影响同一项目里的其他服务。 |
image |
waning/unraid-icon-manager:latest |
要运行的镜像。latest 跟随最新版;希望升级可控时,直接改为 waning/unraid-icon-manager:v0.1.18。 |
container_name |
unraid-icon-manager |
固定容器名,便于在 Unraid 和命令行中查找。若已有同名容器会冲突;本工具不应运行多个副本。 |
ports |
8787:8787 |
左侧是 Unraid 主机端口,右侧是容器内固定端口。只改左侧即可换访问端口,同时必须修改 PUBLIC_BASE_URL。默认监听主机全部网络接口,所以只能在可信局域网使用。 |
environment |
见下表 | 时区、上传限制、图标地址和 Unraid 页面地址全部直接写在 YAML 中;修改后重新创建本工具容器即可生效。 |
volumes |
八项挂载 | 前六项负责 Docker 图标,最后两项启用可选 VM 图标功能。每一项的具体权限见下表。 |
security_opt |
no-new-privileges:true |
禁止容器进程通过 setuid/setgid 等方式获得额外权限;这是额外保护,但不能消除 Docker socket 本身的高权限风险。 |
restart |
unless-stopped |
Unraid 或 Docker 重启后自动恢复;如果你手动停止容器,它不会自己再次启动。 |
| 参数 | 默认/示例 | 是否必填 | 作用 |
|---|---|---|---|
TZ |
Asia/Shanghai |
否 | 容器时区,影响界面与日志中的本地时间显示。 |
ADMIN_TOKEN |
自行生成的随机长字符串 | 是 | 管理员登录令牌,至少 24 个字符;可用 openssl rand -base64 36 生成。绝不能使用示例 CHANGE_ME,也不要提交到公开仓库。 |
TRUSTED_NETWORKS |
RFC1918 + loopback | 是 | 允许访问本服务的逗号分隔 CIDR。建议缩小至实际管理网段;Fastify 不信任可伪造的 X-Forwarded-For。 |
ICON_HOST_ROOT |
/mnt/user/appdata/unraid-icon-manager/icons |
是 | /config/icons 在 Unraid 主机上的对应路径。修改 /config 的主机挂载时,必须同步修改。 |
WALLPAPER_HOST_ROOT |
/mnt/user/appdata/unraid-icon-manager/wallpapers |
是 | /config/wallpapers 在 Unraid 主机上的对应路径,用于复制正确的宿主机路径。 |
COMPOSE_HOST_ROOT |
/mnt/user/docker |
Compose Manager 用户是 | Compose Manager 插件设置中的 PROJECTS_FOLDER。不是该目录时必须修改,否则 Compose 图标不能持久化。 |
MAX_UPLOAD_BYTES |
5242880 |
否 | 单个上传文件的最大字节数,默认 5 MiB。过大的 PNG、SVG 或 WebP 会被拒绝。 |
MAX_WALLPAPER_BYTES |
31457280 |
否 | 单张上传或 URL 下载壁纸的最大字节数,默认 30 MiB。 |
MAX_ICON_GALLERY_BYTES |
524288000 |
否 | 图标图库总配额,默认 500 MiB。达到上限须删除未使用素材后再上传。 |
MAX_WALLPAPER_GALLERY_BYTES |
2147483648 |
否 | 壁纸图库总配额,默认 2 GiB。 |
MAX_MUTATION_QUEUE |
20 |
否 | 排队中的图标写入/同步数量上限;超出会返回 HTTP 429,避免大量重建请求堆积。 |
PUBLIC_BASE_URL |
http://192.168.1.10:8787 |
是 | 写入 Unraid 模板的图标服务根地址,必须从 Unraid 主机自身可访问。不能填容器内部地址或 localhost;端口必须与 ports 左侧的主机端口一致。 |
UNRAID_DOCKER_URL |
http://192.168.1.10:5000/Docker |
是 | 点击刷新 Docker 页面时打开的地址。若 Unraid WebGUI 使用自定义端口,必须把端口写完整。 |
UNRAID_VM_URL |
http://192.168.1.10:5000/VMs |
VM 用户是 | 修改 VM 图标后打开的页面。 |
VM_ICONS_DIR |
/unraid/vm-icons |
VM 用户是 | VM Manager 图标目录的容器路径,一般不要修改。 |
LIBVIRT_URI |
qemu+unix:///system?socket=/var/run/libvirt/libvirt-sock |
VM 用户是 | 显式连接挂载的 Unraid libvirt socket,一般不要修改。 |
Compose 内还有三个固定的容器内环境变量:ICON_CACHE_DIR=/unraid/icon-cache、ICON_CACHE_RAM_DIR=/unraid/icon-cache-ram 和 COMPOSE_PROJECTS_DIR=/unraid/compose-projects。它们必须与对应挂载的容器路径一致,一般不要修改。
| 主机路径 → 容器路径 | 权限 | 是否必需 | 具体作用 |
|---|---|---|---|
/mnt/user/appdata/unraid-icon-manager → /config |
读写 | 是 | 保存数据库及其 WAL 文件、图标/壁纸图库、XML/缓存备份和审计记录;不挂载会导致重建容器后数据丢失。 |
/boot/config/plugins/dockerMan/templates-user → /unraid/templates-user |
读写 | 是 | 原子更新已有 Unraid Docker 模板的 <Icon>,或为没有模板的当前容器创建专用图标元数据模板。 |
/var/lib/docker/unraid/images → /unraid/icon-cache |
读写 | 是 | 备份和更新 Unraid Docker Manager 的持久图标缓存,只处理被修改的目标容器。 |
/usr/local/emhttp/state/plugins/dynamix.docker.manager/images → /unraid/icon-cache-ram |
读写 | 是 | 备份和更新运行时 RAM 图标缓存,让刷新 Docker 页面后立即看到新图标。 |
/mnt/user/docker → /unraid/compose-projects |
读写 | Compose Manager 用户是 | 原子备份并更新所选项目 docker-compose.override.yml 中所选服务的图标标签;如果插件的 PROJECTS_FOLDER 不同,需要同时修改挂载和 COMPOSE_HOST_ROOT。 |
/var/run/docker.sock → /var/run/docker.sock |
只读挂载 | 是 | 读取容器信息;只有用户点击同步时才停止、删除并以相同配置重建所选容器。Docker socket 即使标为 :ro 仍允许高权限 API 操作。 |
/usr/local/emhttp/plugins/dynamix.vm.manager/templates/images → /unraid/vm-icons |
读写 | VM 用户是 | 保存 Unraid VM Manager 实际显示的自定义图标。 |
/var/run/libvirt → /var/run/libvirt |
读写 | VM 用户是 | 挂载动态运行目录;只修改所选 VM 的 vmtemplate@icon,但目录内 socket 授予完整 VM 管理权限。 |
Caution
部署前必须直接修改三个 URL 中的示例 IP。不要填写 localhost。Docker socket 与 libvirt 运行目录都是高权限接口,绝不能把本服务暴露到公网。不要单独映射 /var/run/libvirt/libvirt-sock:Unraid 重启时 libvirt 可能晚于 Docker 创建 socket,Docker 会把不存在的源路径建成目录。
- 选择一个或多个当前容器,或点击单个可编辑容器。
- 粘贴 HTTP(S) 图标 URL、图库地址,或上传图片。
- 应用图标;外部 URL 会先下载到图库并规范化,没有匹配模板时再创建带标记的图标元数据模板。
- 保存后点击同步到 Unraid。工具会更新缓存,并只重建所选容器;Compose Manager 服务会先写回对应 override。同步成功后打开 Docker 页面即可看到新图标。
壁纸图库不会修改 Unraid Docker 页面,只作为持久化素材库使用。顶部可新建分组,上传或 URL 下载时会放入当前分组;每张壁纸可随时改分类、下载、删除,或复制该图片自身的完整 HTTP 地址与完整宿主机文件路径。
每次更新都会把原始 XML 备份到 /config/backups/,并以紧凑的修改前/修改后历史快照记录在最近变更;展开记录可查看完整图标地址。只有最新且仍与当前模板一致的修改会显示回滚,回滚会同时恢复模板与两级 Unraid 图标缓存。若该审计记录创建了模板,只有在模板仍未被外部修改时才会删除该生成模板。回滚后还需点击同步,才能恢复运行容器不可变的图标标签。
- 升级前备份
/mnt/user/appdata/unraid-icon-manager;其中包含 SQLite 数据库、图标图库、审计记录与备份。 - Compose 安装如需固定版本,直接把
image改为目标完整标签(例如waning/unraid-icon-manager:v0.1.21),然后只更新本工具:
docker compose pull unraid-icon-manager
docker compose up -d --no-deps unraid-icon-manager- 不要为了升级本工具执行会影响其他服务的
docker compose down。Unraid 图形界面安装时,也只更新unraid-icon-manager的镜像标签。 - 升级后检查
http://你的地址/api/health返回的ok和版本,并登录 Web UI 确认 Docker/模板/VM 连接状态。首次升级到0.1.22需要新增ADMIN_TOKEN;未填写时容器会安全地拒绝启动。 - 从最近变更回滚单项图标并再次点击同步。如需回退本工具版本,选择旧镜像标签,同时保留
/config和所需挂载。
npm ci
npm run dev
npm run check本地开发变量以 src/server/config.ts 的默认值为准;Compose 部署参数全部直接写在 docker-compose.yml 中。生产镜像支持 linux/amd64 与 linux/arm64。
推送例如 v0.1.21 的标签后,GitHub Actions 会发布以下 Docker Hub 标签:
waning/unraid-icon-manager:latestwaning/unraid-icon-manager:v0.1.21waning/unraid-icon-manager:v0.1
仓库维护者需要配置 DOCKERHUB_USERNAME=waning 与 DOCKERHUB_TOKEN 两个 GitHub Actions Secret。凭据不会保存在仓库中。
请阅读 SECURITY.md。外部图片导入只接受经校验的公网 HTTP(S) 地址与栅格图片,阻止本机/私网/保留地址并限制 DNS、连接、总时长、重定向和字节数;考虑到公开图标站常使用自定义端口,公网自定义端口仍受支持。Docker socket、模板、两个缓存与 Compose Manager 项目挂载都属于特权主机访问。只挂载插件实际配置的 PROJECTS_FOLDER,不要扩大到整个 /mnt/user、/boot 或 /var/lib/docker。请私下报告漏洞,且不要上传包含私有 URL、路径、挂载或密钥的诊断信息。
如果这个工具对你有帮助,欢迎扫码支持后续维护。