SolarPanel — 为什么造了一个导航面板

作者:Zero 发布时间: 2026-09-09 阅读量:44 评论数:0

前言

先问个问题:你浏览器首页是什么?

我之前很长一段时间用的是一个挺有名的开源导航项目,功能也够用,但总觉得哪里不对

后来又试了几个,都不满意。某天深夜,我盯着浏览器空白页想:==不就是个导航面板吗?能有多难?==

然后我就开始写了。

事实证明,一个看起来简单的东西,真做起来细节能把人淹死。不过也好,有了AI的辅助,一路踩坑一路补,现在 v2.0 也算有模有样了,名字叫 SolarPanel

演示站:test.ozero.top GitHub开源地址:https://github.com/Ozero-top/Solar-Panel

为什么叫 SolarPanel

说起名字还有点好笑。最开始我想叫 "NavPanel",不适合;叫 "StartPage",又太直白。后来我看着界面上一排排卡片,突然觉得它们长得像太阳能板 —— 一块一块的,整整齐齐,吸收信息能量(好吧这个比喻有点牵强,但当时就是这么想的)。

而且 "solar" 有阳光的意思,我希望这个面板用起来让人觉得温暖舒服,而不是冷冰冰的工具。正好主题也走了柔和路线,17 种主题里有一大半都是暖色调的,名字也对得上。

就这么定了。

我想要的导航面板长什么样

做之前我列了几个需求,现在回头看,这些需求基本决定了整个项目的走向:

  • 🛠 一切都能后台配置 — 站点标题、Logo、壁纸、搜索引擎、分组卡片……改什么都不用碰代码,后台点几下就行。

  • 🚀 部署要简单 — 最好 Docker 一行命令跑起来。同时照顾一下用宝塔的朋友,PHP 版也得有。

  • 🎨 好看是第一生产力 — 界面要柔和舒服,不能杀马特。多做几套主题,浅色深色都得有。

  • 🔒 数据自己拿着 — 可自托管,数据存在自己的服务器上,不依赖任何第三方服务。

看起来要求不多对吧?真做起来你就知道了,每一条背后都是一堆细节。

Demonstration.png

两个版本的故事:Go 和 PHP 并行开发

这可能是这个项目最有意思的地方——我同时维护了两个版本:

对比项

Docker / Go 版

PHP 版

技术栈

Go + Gin + GORM,单二进制

PHP 原生,无框架

数据库

SQLite 内置,不用装数据库

MySQL 5.7+

部署方式

docker compose up -d 搞定

宝塔 / 1Panel / 虚拟主机

镜像大小

46MB,多架构支持

上传文件就能用

为什么要做两个版本?说起来也简单——我自己的服务器用 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 项目吗",真做起来才发现:

  1. 用户体验的细节是无底洞 —— 拖拽的手感、动画的时长、错误提示的文案,每一样都要磨

  2. 安全永远比你想的重要 —— 你觉得不会有人攻击一个小导航站?错了,bot 扫端口可比你勤快多了

  3. 兼容两个版本比想象中麻烦 —— 但也倒逼我把接口设计得更规范

  4. 在线升级功能看起来简单,做起来全是坑 —— 权限、回滚、原子替换、OPcache 缓存……每一项都可能翻车

不过最开心的还是看到有人用了之后说 "这个面板真好看"、"部署好简单"。那种感觉,懂的都懂。

接下来打算做什么

目前 v2.0 已经比较稳定了,但还有不少想做的:

  • 更多的主题?(其实 17 个已经够多了,但总忍不住想加)

  • 小组件系统,比如待办清单、便签什么的

  • 更好的移动端体验

  • 更多的新闻数据源和自定义能力

慢慢来,反正这是我自己每天都要用的东西,就当给自己做工具了。


如果你也想要一个自己掌控、好看又好用的导航面板,可以试试 SolarPanel。项目是 MIT 协议开源的,随便用、随便改。

当然,如果你用了之后觉得哪里不好用、想加什么功能,欢迎提 Issue 或者 PR。一个人做的东西总归有局限,大家一起折腾才有意思。

感谢读到这里,下次见 ☀️

评论