有多少人跟我一样,电脑里存了一堆SVG图标文件,真正要用的时候却翻半天找不到合适的?我最近折腾Home Assistant的自动化面板,想给一堆设备换图标,默认图标库就那么几百个,用起来总觉得不够顺手。后来在飞牛fnOS上部署了MyIcon这套本地图标资源库,总算把图标这件事收拾利索了。这篇文章就把完整的部署过程和踩坑记录分享出来,包括为什么要在NAS上自建图标库、部署前该怎么规划目录和端口、两种部署方式怎么选,以及后续批量导入和日常维护的实操细节。如果你也在用飞牛,或者准备折腾自托管服务,这篇应该能帮你少走不少弯路。
1. 为什么放着现成的图标网站不用,偏要在NAS上折腾一套
先说一个很实际的问题:我们平时找图标,第一反应都是打开那些知名的图标网站。我最早也是这么干的,但用久了会发现几个绕不开的痛点。
公共图标网站的体验问题其实很典型。搜索“箭头”这样的通用词,出来的结果动辄几千个,翻页翻到怀疑人生;想要下载SVG原文件,不是让你注册账号,就是提示“仅限高级会员”;就算下载下来了,文件名往往是一串乱码,过两天再想找同系列的图标,根本对不上号。最要命的还是版权问题,很多免费图标的授权范围写得含糊,用在个人项目里还好,一旦牵扯到商业用途,心里总是不踏实。
所以我才动了自建图标库的念头。说白了,我要的不是一个“更多图标的网站”,而是一个我自己能完全掌控的图标管理系统。MyIcon解决的就是这个问题:它是一个可以跑在内网里的图标资源库,把SVG文件统一收进来,打上分类和标签,需要的时候直接在网页里搜索、预览、复制、下载,所有图标都存在自己的NAS上,速度当然快,也完全不依赖外部服务。
可能有朋友会说,这个需求听起来也不是特别刚需?但如果你跟我一样家有NAS,还喜欢折腾智能家居、个人博客、甚至偶尔画点PPT,图标其实是高频素材。我算了一笔账:过去我找个图标平均要开三个网页、花十分钟;现在打开MyIcon,输入关键词到拿到SVG链接,基本上十秒以内。半年下来省下的时间,早就覆盖了当初部署这套系统花掉的周末下午。
还有个隐私上的考量。很多在线图标库会记录你的搜索行为和下载记录,虽然不是什么敏感数据,但既然NAS已经放在家里了,把素材库也搬回来,从数据归属的角度看更安心。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 先搞清楚MyIcon能干什么,再决定怎么部署
在动手部署之前,我建议你先花几分钟想清楚自己到底需要MyIcon的哪些能力。这套工具不是那种“装完就完事”的应用,它的价值在于日常使用,所以提前了解功能边界,能避免部署完觉得“没什么用”的尴尬。
以我用的这版MyIcon为例,核心功能大致可以分成四块。
图标入库与整理。它支持在网页端单个上传SVG文件,也支持把一批文件丢进NAS的指定目录,再通过扫描批量导入。入库之后可以建分类、打标签,相当于给图标做了一套索引。比如我会分成“箭头”“设备”“品牌”“家居”几个大类,每个类目下再按场景打标签,搜索的时候就很精准。
检索与预览。网页端带一个搜索框,输入关键词能实时过滤图标,而且支持直接预览不同尺寸下的显示效果。这一点特别实用——很多SVG在小尺寸下细节糊成一团,预览一下就能筛掉一批不合适的。
导出与集成。这是MyIcon最有价值的部分,它不只是让你“看图”,还能直接把图标以多种形式输出。常见的导出方式包括SVG源文件、PNG位图、CSS雪碧图、JavaScript模块,以及iconfont字体文件。这意味着它可以接进不同的工作流:内网页面直接用URL引用、项目里打包成JS模块、设计稿里用字体文件等等。
API能力。我用的版本提供了一套简单的REST接口,支持按关键词搜索图标、按ID获取文件、拉取某个分类下的全部图标。这套API是后面把它接到各种自动化面板、内部系统里的关键,相当于你拥有了一个私有的图标CDN。
下面这张表是我使用过程中对“公共图标站”和“本地图标库”的直观对比,也说明了我为什么最终选择自建。
| 对比维度 | 公共图标网站 | MyIcon本地图标库 |
|---|---|---|
| 响应速度 | 受网络影响,时快时慢 | 内网秒开,几乎无延迟 |
| 版权可控性 | 授权条款模糊,需逐一核对 | 图标来源由自己控制 |
| 文件管理 | 下载后散落各处,易丢失 | 统一归档,分类检索 |
| 可用性 | 网站改版、停服可能导致素材失效 | 数据和系统都在本地,长期可用 |
| 扩展集成 | 以站内使用为主 | 可通过API接入自己的系统 |
当然MyIcon也不是万能的。它本身不生产图标,所有图标都需要你自己去找来源,它做的是“整理”和“分发”这两件事。所以我的建议是:如果你只是偶尔找一两个图标,没有集中管理的需求,那没必要折腾;但如果你和我一样想把图标资产沉淀下来,这工具绝对值得部署。
3. 部署前先做功课:目录、端口、权限这三样别偷懒
确定了要用MyIcon之后,我没有急着开Docker面板,而是先花了十分钟做规划。这十分钟决定了我后面少踩了多少坑。尤其飞牛fnOS这套系统,虽然Docker管理界面做得已经挺顺手,但如果你没想清楚映射关系就乱点一通,后面数据迁移、权限排查的时候能把你折腾到怀疑人生。
存储路径规划。飞牛的系统盘和数据盘是分开的,我习惯把所有Docker应用的数据统一放在存储池下一个叫docker的目录里。MyIcon我单独建了一个子目录,结构是这样:
text复制/vol1/docker/myicon/
├── data/ # 图标索引、配置等持久化数据
└── import/ # 批量导入SVG的临时目录
data目录是MyIcon真正要长期写入的地方,相当于它的“数据库”,必须挂载到容器里并持久化;import目录是我后续批量导入图标用的中转站,放进去的文件通过MyIcon扫描后会自动入库。把这个结构拆清楚,后面备份和迁移就只需要打包myicon这一个文件夹。
端口选择。很多朋友部署的时候习惯直接把容器镜像文档里写的默认端口映射到宿主机相同端口,比如8080:8080。这在飞牛上很容易出问题,因为NAS上跑着的应用不止一个,Web界面、媒体服务、下载工具各自占着一堆端口,保不齐就撞上了。我的做法是尽量映射到一个不常见的高位端口,比如9876,宿主机左侧用高位端口,右侧保留容器内部端口,映射写法是9876:8080。这样记起来也不费劲,访问地址就是http://飞牛IP:9876。
权限设置。这是最容易被忽略的一点。容器里的进程是以某个Linux用户身份运行的,它必须对挂载进去的data目录有读写权限,否则启动后你会发现界面能打开,但图标上传、索引写入全部失败,日志里一屏权限报错。我用的这版MyIcon支持通过PUID和PGID两个环境变量指定运行用户,直接设成1000:1000就行,因为飞牛默认的普通用户UID通常是1000。如果你不确定,可以在SSH里执行id命令确认一下,然后把对应的UID/GID填进去。
时区环境变量。容器默认时区往往是UTC,会导致MyIcon里记录的上传时间、更新时间跟北京时间差八个小时。解决方案就是在环境变量里加一行TZ=Asia/Shanghai,小事情,但能避免日后看时间总觉得哪里不对劲。
我还想分享一个小技巧:第一次部署正式环境之前,可以先不改名字、不挂目录,直接用docker run跑一个临时容器,观察它的默认端口、日志输出和数据目录结构,确认清楚之后再正式创建。这套“先探路再正式开工”的思路,对于不熟悉的镜像特别管用,能省掉很多想当然的返工。
4. 两种部署方式实测:图形界面创建还是SSH跑Compose
飞牛fnOS的Docker能力分成两种形态:一种是系统自带的Docker管理界面,另一种是通过SSH进入终端直接执行命令。两种我都试过,各有适用场景,下面分别说一下操作过程。
4.1 方式一:在飞牛Docker界面里用图形化方式创建
飞牛的Docker页面应该是内置了很多NAS玩家熟悉的容器管理逻辑,操作路径是这样:打开飞牛桌面的Docker应用,先到“镜像”页面,在搜索框里输入MyIcon的镜像名,点击拉取。拉取完成后,选中镜像点“创建容器”。
创建容器时主要填下面几项:
- 容器名称:填
myicon,方便后面排查。 - 端口映射:添加一条,宿主机端口填
9876,容器端口填镜像文档里说明的端口(我这版是8080)。 - 存储空间映射:把
/vol1/docker/myicon/data映射到容器内的/app/data;把/vol1/docker/myicon/import映射到容器内的/app/import。 - 环境变量:添加
TZ=Asia/Shanghai、PUID=1000、PGID=1000。 - 重启策略:选择
unless-stopped,这样NAS重启后容器会自动拉起来,不用手动去点。
图形界面最大的好处是直观,每个映射关系都一目了然,适合不常碰命令行的朋友。但也有个问题:它默认设置的网络模式、DNS这些参数有时候不好细调,而且如果你把容器的配置搞乱了,重置起来比较麻烦。
4.2 方式二:SSH进终端,用Compose文件管理
我个人更推荐这种方式,因为Compose文件本身就是配置清单,改起来、备份起来、迁移起来都方便得多。用SSH登录飞牛后台之后,执行sudo -i切到root,然后:
bash复制mkdir -p /vol1/docker/myicon/{data,import}
cd /vol1/docker/myicon
在/vol1/docker/myicon下创建docker-compose.yml,内容大致是这样:
yaml复制services:
myicon:
image: your-registry/myicon:latest # 换成你实际拉取的镜像名
container_name: myicon
restart: unless-stopped
ports:
- "9876:8080" # 左侧是宿主机访问端口,右侧是容器内服务端口
environment:
- TZ=Asia/Shanghai
- PUID=1000
- PGID=1000
volumes:
- /vol1/docker/myicon/data:/app/data
- /vol1/docker/myicon/import:/app/import
保存之后,在同一个目录下执行:
bash复制docker compose up -d
等待镜像拉取并启动,然后用docker ps看一下容器状态。如果STATUS列显示Up,基本就成了。接下来在浏览器里访问http://飞牛IP:9876,应该能看到MyIcon的界面。
两种方式的取舍,我的体会是:如果只是临时跑一跑,用图形界面省事;如果打算长期使用或者日后要升级迁移,一定要用Compose。Compose把环境变量、端口、挂载目录这些信息都固化在文件里了,换一台机器部署时直接把文件拷过去、改一下路径就能用,不需要在图形界面里一项项重新填。
4.3 启动后的验证清单
容器起来不代表万事大吉,我会按下面几步快速验证一次:
- 浏览器打开
http://NAS_IP:9876,确认页面能正常加载。 - 随便上传一个SVG测试文件,看看能不能出现在图标列表里。
- 执行
docker logs -f myicon,观察有没有输出异常报错。 - 重启一次容器,确认数据还在,索引没有丢失。
这四步都过了,基本说明部署是健康的。我也遇到过容器状态正常、页面却一直转圈的情况,后面在踩坑章节专门讲那次排查过程。
5. 把图标喂进去:批量导入和日常整理的实操方案
部署成功只是开始,真正让MyIcon发挥价值的是“把图标库用起来”这件事。我见过不少朋友部署完就往那儿一放,过了两周发现还是空目录,原因无非是手动一个个上传太累,又不知道该怎么批量操作。下面这套流程是我整理好的,照着做基本能顺下来。
5.1 命名规范决定你后面好不好搜
SVG文件在入库之前,一定要先规范命名。MyIcon搜索图标时依赖文件名和标签,如果你上传的文件名叫未命名-1234.svg,那跟没上传有什么区别?
我的命名规则很简单:统一用小写字母和连字符分隔,比如arrow-right.svg、device-cctv.svg、brand-github.svg。这套规范跟Material Design Icons的命名风格保持一致,好处是以后从网上找图标时可以直接照着改,搜索关键词也能对上。命名这件事在批量导入前做,成本最低,一旦入库之后再去改名,索引里的记录跟文件对不上,处理起来很麻烦。
5.2 批量导入的正确姿势
MyIcon一般会在import目录里做扫描导入。实际操作时,我会先从网上下载一批图标到电脑,简单筛选一遍,按照上面说的规范改好文件名,然后通过飞牛的文件管理器或者SMB共享把它们传到/vol1/docker/myicon/import目录里。
如果你的图标散落在NAS其他目录,也可以在SSH里做个集中归档:
bash复制cd /vol1/docker/myicon/import
find /vol1/素材库/svg -name "*.svg" -type f -exec cp {} . \;
把路径替换成你实际的目录就行。拷贝完成后,回到MyIcon后台点一下“扫描导入”,系统会自动把import目录里的新文件入库。整个流程跑顺之后,图标入库就是“下载-改文件名-丢目录-点扫描”四步。
5.3 分类和标签怎么搭
批量导入完成之后,千万别急着收工,分类和标签才是日常使用效率的关键。我的建议是先从“使用场景”出发建分类,而不是从“图标来源”出发。比如我建的是“箭头与指示”“设备与硬件”“用户与账户”“品牌标识”“媒体控制”这几个类,因为我是按场景找图标的。等类建好之后,再把每个类里的图标过一遍,补上关键词标签。
举个具体例子:一个电源开关图标,我会放进“设备与硬件”类,同时打上power、switch、socket、energy这组标签。这样我不管是想找“电源”还是“开关”,都能搜到它。刚开始整理会比较花时间,但后面每次搜索都能找回这段时间。
5.4 通过API把图标接到你的代码里
整理得差不多了,就该发挥MyIcon的API能力了。我用的版本提供了一个简单的搜索接口,比如在终端里执行:
bash复制curl "http://192.168.1.100:9876/api/icons?q=arrow&format=json" | jq .
返回结果里会包含匹配图标的ID、文件名、分类等信息。拿到ID之后,可以直接构造文件直链:
bash复制http://192.168.1.100:9876/api/icons/arrow-right.svg
这个链接可以直接用在<img>标签或者CSS里:
html复制<img src="http://192.168.1.100:9876/api/icons/arrow-right.svg" alt="arrow-right" />
也可以给需要图标的内部网页统一走这个地址,等于把NAS变成了一台内网图标服务器。如果你的项目是前端工程化那种,还可以用MyIcon导出的JS模块,直接把图标作为组件引入,不需要自己维护一堆SVG文件了。
6. 从图标库到业务系统:接进网站、文档和自动化面板
MyIcon真正值钱的地方在于“接出去”。如果只是自己在网页后台点点,那它还只是个加强版文件夹;只有把它接进实际项目里,你才会发现本地图标库有多好用。
内网页面引用。我自己的一个导航页,之前图标都是放在项目目录里的静态文件,每次加新图标都要重新部署一次。现在直接把图标地址指向MyIcon的API,页面运行时实时加载,加图标只需要往NAS里丢文件,刷新页面就生效。这里有一点要注意:如果页面运行在NAS之外的其他机器,引用地址要用局域网IP而不是localhost;如果页面本身也在同一台飞牛上,也可以考虑用飞牛的内网主机名,避免以后IP变了还得批量改。
生成雪碧图和iconfont。对于传统多页面网站,逐个请求SVG不是最优解,更好的做法是把一组常用图标合成一张雪碧图,或者生成一个iconfont字体文件。MyIcon支持选定一个分类或标签下的图标,导出成CSS Sprite或iconfont文件包。我把常用图标单独建了一个“全局导航”标签,所有站点通用的图标都打上这个标签,需要更新时直接导出文件替换,成本很低。
自动化面板和智能家居场景。这也是我最初搞这套的动机。很多自动化面板对图标的支持其实有限,最常见的接入方法是把图标文件放到面板服务器可访问的目录里,再在卡片或面板配置中指定图片路径。比如Home Assistant用户,可以把MyIcon导出的SVG文件放到HA的www/icons目录下,然后自定义卡片里用/local/icons/xxx.svg引用。原理上就是“图标文件先落在本地,再让面板去引用”,MyIcon在这里承担的是素材管理和快速检索的角色,比你自己手工管理一堆文件高效得多。
还有一类玩法是把MyIcon的只读API暴露给局域网内的同事或朋友。不过这里必须强调一句:除非你明确知道自己在干什么,否则不要轻易把MyIcon的管理端口暴露到公网。它本身不是为公网安全模型设计的,直接暴露会有被陌生人上传脏文件甚至改配置的风险。需要公网访问的场景,至少要在前面套一层带身份验证的反向代理,并且把API设置成只读模式。
7. 别急着收工:权限、端口、备份和升级,这些都是实战排过来的坑
最后这部分算是我觉得本篇最有价值的内容了。部署MyIcon本身不复杂,难的是部署之后遇到问题怎么定位、怎么避免数据丢失。下面这些坑都是我在飞牛上真实踩过的,写出来给你当参考。
7.1 端口冲突排查:容器明明在跑,页面就是打不开
有段时间我改过一次端口映射,改成9880:8080之后,浏览器访问NAS_IP:9880一直超时。看Docker列表里容器是Up状态,也没报错误,就很迷惑。
后来一步步排查才发现,问题不在容器,而在飞牛系统层面。我用的这个端口已经被另一个系统服务占用了,虽然容器端口映射显示绑定成功,但系统防火墙或服务监听把它挡在了外面。排查方法很简单,在SSH里执行:
bash复制docker port myicon
ss -lntp | grep 9880
docker port会显示容器实际映射出去的端口,ss则能看到这个端口被哪个进程占用。如果发现端口被占,换个高位端口重新映射就好,同时记得在飞牛的防火墙规则里放行新端口。
7.2 权限不对,图标库里满是写入错误
还有一次是容器能启动、页面能打开,但上传SVG一直失败,后台日志里全是EACCES: permission denied。原因就是我当时图省事,直接把宿主机上一个旧目录挂给了容器,那个目录的属主是root,而容器内的进程以UID 1000运行,没有写权限。
解决办法分两步:
bash复制chown -R 1000:1000 /vol1/docker/myicon/data
chown -R 1000:1000 /vol1/docker/myicon/import
执行完再重启容器。如果你挂载的目录需要被多个容器共用,就要考虑是不是换一个统一权限规划,而不是每个容器都去改属主。这个例子也说明,部署前规划目录时顺便把权限规划好,能省掉后续一大半的排错时间。
7.3 备份和迁移:把整个图标资产装进一个文件夹
MyIcon的数据都落在/vol1/docker/myicon/data目录里,所以备份策略非常简单:把这个目录打包带走即可。我一般用系统自带的任务计划,每周跑一次备份脚本,把myicon整个目录复制到另一块硬盘或挂载的备份存储上。
跨机器迁移时注意顺序:先在新机器上创建好Compose文件,再关停旧机器上的容器,然后把整个myicon目录通过文件同步工具传到新机器,最后在新机器执行docker compose up -d。迁移过程中最好不要在旧机器上继续往里加图标,否则新机器上还没同步完就可能出现版本不一致。我习惯在正式同步前先停掉容器,保证数据文件一致性。
7.4 升级前必做两件事:备份数据、看官方变更说明
MyIcon这类项目迭代不算快,但升级时还是要注意。我最开始升级的方式很粗暴,直接拉新镜像然后重启,结果有一次新版改了内部数据目录结构,导致图标列表全部消失。那次幸好有备份,恢复之后我反思了一下,升级的正确姿势是先备份data目录,再看一眼项目更新说明里有没有涉及数据迁移的提示,确认之后执行:
bash复制cd /vol1/docker/myicon
docker compose pull
docker compose up -d
升级完成之后清一下浏览器缓存再访问,因为前端资源可能缓存了旧版本,界面表现异常时先别慌,很多时候是缓存问题,不是数据问题。
7.5 强制关机导致的索引异常
飞牛断电或异常重启后,MyIcon偶尔会出现“图标列表能正常打开,但搜索结果为空”的怪现象。这个大概率是索引文件没有正常落盘导致的。处理办法不复杂,先把容器停掉,备份data目录,然后找到索引文件把它删除或移走,再启动容器让系统重新构建索引。不会影响SVG原文件本身,最多重新整理一遍标签,算是应急方案,但也说明了“记得备份”这件事有多重要。
写在最后的工作流
折腾完这套MyIcon之后,我现在找图标已经形成了固定习惯:在素材网站看到一个合适的SVG,下载后立刻按命名规范改好文件名,丢进飞牛的import目录,回到MyIcon点一次扫描,然后继续做手头的事。所有图标资产都沉淀在NAS本地,网站、自动化面板、文档里的引用地址稳定不变,再也不用担心图标网站改版或者素材文件散落得到处都是了。如果你也想搭一套,建议找个周末按这篇文章的步骤来,过程中对Docker的目录映射、权限控制、Compose管理这些基础操作也能顺带掌握,这笔时间花得值。
