前言
先问个问题:你浏览器首页是什么?
我之前很长一段时间用的是一个挺有名的开源导航项目,功能也够用,但总觉得哪里不对
后来又试了几个,都不满意。某天深夜,我盯着浏览器空白页想:==不就是个导航面板吗?能有多难?==
然后我就开始写了。
事实证明,一个看起来简单的东西,真做起来细节能把人淹死。不过也好,有了AI的辅助,一路踩坑一路补,现在 v2.0 也算有模有样了,名字叫 SolarPanel。
演示站:test.ozero.top GitHub开源地址:https://github.com/Ozero-top/Solar-Panel
为什么叫 SolarPanel
说起名字还有点好笑。最开始我想叫 "NavPanel",不适合;叫 "StartPage",又太直白。后来我看着界面上一排排卡片,突然觉得它们长得像太阳能板 —— 一块一块的,整整齐齐,吸收信息能量(好吧这个比喻有点牵强,但当时就是这么想的)。
而且 "solar" 有阳光的意思,我希望这个面板用起来让人觉得温暖舒服,而不是冷冰冰的工具。正好主题也走了柔和路线,17 种主题里有一大半都是暖色调的,名字也对得上。
就这么定了。
我想要的导航面板长什么样
做之前我列了几个需求,现在回头看,这些需求基本决定了整个项目的走向:
🛠 一切都能后台配置 — 站点标题、Logo、壁纸、搜索引擎、分组卡片……改什么都不用碰代码,后台点几下就行。
🚀 部署要简单 — 最好 Docker 一行命令跑起来。同时照顾一下用宝塔的朋友,PHP 版也得有。
🎨 好看是第一生产力 — 界面要柔和舒服,不能杀马特。多做几套主题,浅色深色都得有。
🔒 数据自己拿着 — 可自托管,数据存在自己的服务器上,不依赖任何第三方服务。
看起来要求不多对吧?真做起来你就知道了,每一条背后都是一堆细节。

两个版本的故事:Go 和 PHP 并行开发
这可能是这个项目最有意思的地方——我同时维护了两个版本:
为什么要做两个版本?说起来也简单——我自己的服务器用 Docker 很方便,但有些朋友只有一台宝塔面板的虚机,让他们装 Docker 等于要了命。
一开始我只写了 PHP 版,毕竟部署门槛最低。后来用着用着觉得 SQLite 真香,为啥还要单独装个 MySQL?于是就有了 Go 版。Go 编译出来是个单二进制,塞进 Docker 镜像里才 46MB,启动秒开,内存占用也低,跑在 NAS 上特别舒服。
💡 一个有意思的发现
两个版本功能完全一致,但用户群体差别很大。Docker 版用户普遍更 "技术宅",会提 PR、会自己改代码;PHP 版用户则更偏向 "拿来就用",问题大多集中在部署和配置上。挺有意思的观察。
当然,维护两个版本也有代价——每次加新功能都要写两遍。不过前端是共用的(纯静态),后端接口也尽量保持一致,所以还能接受。
聊聊那些我觉得挺棒的功能
说几个自己做的时候觉得 "哇,这个功能真的爽" 的地方吧。
主页拖拽排序卡片
大多数导航面板的排序都要去后台点上下箭头,贼麻烦。我做的时候就想:能不能直接在主页拖?挺有名的开源导航项目也有这个功能
于是就有了这个功能——管理员登录后,在主页直接拖拽卡片排序,拖完有保存和取消按钮,还有守卫确认防止误操作。
说起来简单,但交互细节磨了好久:
拖到分组边界怎么办?
排序失败怎么回滚?
拖拽时的视觉反馈够不够?
不过真的好用,改完我自己每天都要拖两下(奇怪的习惯)。
17 种主题,不是说着玩的
对,你没看错,17 种。Soft 柔和浮雕、Nature 自然拟态、Holo 全息渐变、Clay 黏土形态、Neumorphism 新拟物、Ghibli 吉卜力……每一种都适配了浅色、深色、跟随系统三态。
做主题的那段时间我感觉自己像个调色师,每天盯着色板调参数。现在回头看确实有点上头,要是有用户说 "这个主题太好看了" 的时候,还是挺开心的。
热点新闻视图
这是我自己用得最多的功能之一。主页搜索框下面一键切换 "导航站 / 热点新闻",不用开新标签页就能看知乎热榜、微博热搜、B站排行榜、HN 什么的。
内置了 ==24 个数据源==,还支持自定义 RSS。早上起来刷一眼,今天有什么瓜都知道了(划掉)。
PWA + 离线
这个完全是我个人的刚需——我想把导航站装成一个独立的桌面应用,点一下就开,像原生 App 一样。
所以 PWA 支持从一开始就做了。Service Worker 缓存策略也调了好久:
API 和 HTML 走网络优先
静态资源走 Stale-While-Revalidate
离线了还有兜底页面
内网用 HTTPS + 自签名证书就能装,Docker 版甚至自动给你生成证书。
安全这块,我是认真的
说起来可能有点夸张,但一个导航面板的安全问题,我前前后后想了好多。
原因很简单:导航站是你浏览器的第一站,上面存着你所有常用网站的链接,有些可能还是内网地址。如果这个面板被人搞了,后果不堪设想。
所以我在安全上下的功夫可能比一些功能还多:
🛡 SSRF 防护 — 服务端抓取站点图标前,DNS 解析后校验 IP,回环地址、私网、云元数据地址全部拦截。这个是重灾区,很多导航站都没做。
🎫 CSRF 令牌 — 所有写接口都要带 CSRF Token,登录后还会轮换。
🔐 登录防爆破 — 连续 8 次失败直接锁 15 分钟。
📱 两步验证 (TOTP) — 管理员可以开 Google Authenticator 那种动态码。
📤 文件上传 — 扩展名白名单 + magic byte 真实内容检测 + 随机文件名,上传目录还禁止执行脚本。
🚦 公开接口限流 — 公开数据接口有滑动窗口限流,重启不丢。
当然,没有绝对的安全。但能做的我都尽量做了,至少比 "admin/admin123 直接进后台" 那种强多了。
⚠️ 一个重要提醒
Docker 版默认密码是
admin / admin123,这是公开镜像里人人都知道的。首次登录一定要立刻改密码,公网部署的话还要改端口、开 HTTPS、最好限制来源 IP。==改密码前千万别暴露到公网。==
部署到底有多简单
吹了这么多,部署到底方不方便?
Docker 版就几行配置:
services:
solarpanel:
image: ovitor/solarpanel:latest
container_name: solarpanel
restart: unless-stopped
ports:
- "18080:18080"
volumes:
- ./data:/app/data
environment:
- TZ=Asia/Shanghai然后 docker compose up -d,完事。
内网想用 HTTPS 装 PWA?加个 HTTPS_PORT=18443,容器自动生成自签名证书,连证书都不用你管。
PHP 版也不复杂,上传文件后访问安装向导,填个数据库信息点一下就装好了。宝塔、1Panel、虚拟主机都能跑。
做这个小项目学到了什么
说实话,比我想象的多。
以前总觉得 "不就是个 CRUD 项目吗",真做起来才发现:
用户体验的细节是无底洞 —— 拖拽的手感、动画的时长、错误提示的文案,每一样都要磨
安全永远比你想的重要 —— 你觉得不会有人攻击一个小导航站?错了,bot 扫端口可比你勤快多了
兼容两个版本比想象中麻烦 —— 但也倒逼我把接口设计得更规范
在线升级功能看起来简单,做起来全是坑 —— 权限、回滚、原子替换、OPcache 缓存……每一项都可能翻车
不过最开心的还是看到有人用了之后说 "这个面板真好看"、"部署好简单"。那种感觉,懂的都懂。
接下来打算做什么
目前 v2.0 已经比较稳定了,但还有不少想做的:
更多的主题?(其实 17 个已经够多了,但总忍不住想加)
小组件系统,比如待办清单、便签什么的
更好的移动端体验
更多的新闻数据源和自定义能力
慢慢来,反正这是我自己每天都要用的东西,就当给自己做工具了。
如果你也想要一个自己掌控、好看又好用的导航面板,可以试试 SolarPanel。项目是 MIT 协议开源的,随便用、随便改。
当然,如果你用了之后觉得哪里不好用、想加什么功能,欢迎提 Issue 或者 PR。一个人做的东西总归有局限,大家一起折腾才有意思。
感谢读到这里,下次见 ☀️