每天打开浏览器,十几个标签页——RSS、行情、服务器面板、GitHub Release、天气。Glance 干的事就是把这些收拢到一个页面里,而且整个程序不到 20MB。
一、项目介绍
官方对它的定义只有一句:a lightweight, highly customizable dashboard that displays your feeds in a beautiful, streamlined interface。
三个关键词值得拆开看:
- lightweight:单二进制小于 20MB,Docker 镜像同样小。官方特别强调「低内存占用、极少依赖、极简 vanilla JS」,没上 React 那套
- highly customizable:布局可调、页面数量不限、每个组件都有大量参数、部分组件支持多种样式、还能塞自定义 CSS
- feeds:它的核心不是「监控」,而是「信息流聚合」。RSS、Reddit、Hacker News、YouTube、Twitch 这些内容源才是主角,服务器指标只是其中一类组件
技术上它用 Go 写,配置全是 YAML。没有数据库,没有后台管理界面,改配置就是改文件然后重启。这个设计决定了它的部署极简,也决定了它的能力边界——它不是一个「可视化监控平台」,别拿它跟 Grafana 比。
仓库 3.7 万 star,AGPL-3.0 许可。
二、功能拆解
内置组件
官方 README 列出的清单:
- RSS feeds:最核心的组件,任意 RSS/Atom 源
- Subreddit posts:抓指定 subreddit 的帖子
- Hacker News posts:HN 热帖
- Weather forecasts:天气预报,支持公制/英制、12/24 小时制
- YouTube channel uploads:按 channel ID 追更
- Twitch channels:看谁在直播
- Market prices:股票、加密货币行情
- Docker containers status:容器状态与资源占用
- Server stats:CPU、内存、磁盘
- Custom widgets:自定义组件,README 里给了四种做法
社区还维护了一批额外组件:https://github.com/glanceapp/community-widgets
自定义组件的四种方式
官方 FAQ 明确给了四条路,按复杂度递增:
| 方式 | 用途 |
|---|---|
iframe |
直接嵌别的网站页面 |
html |
塞静态 HTML 片段 |
extension |
从 URL 抓 HTML 渲染 |
custom-api |
从 URL 抓 JSON,用自定义 HTML 模板渲染 |
custom-api 是能力最强的一个——只要对方有 JSON API,你就能把它变成 Glance 上的一个卡片。
性能与外观
- 缓存机制:页面加载时才拉数据,然后缓存。每个组件的默认缓存时长不同,可单独配置。后台不会定时请求,这一点官方 FAQ 说得很清楚
- 官方数据:未缓存的页面通常 1 秒内加载完(取决于网速和组件数量)
- 移动端适配:官方专门做了手机端布局
- 主题:改几个数字就能出主题,也有一批现成的(
docs/themes.md)
三、官方链接
- GitHub 仓库:https://github.com/glanceapp/glance
- 配置文档:https://github.com/glanceapp/glance/blob/main/docs/configuration.md
- 预置页面示例:https://github.com/glanceapp/glance/blob/main/docs/preconfigured-pages.md
- 主题列表:https://github.com/glanceapp/glance/blob/main/docs/themes.md
- 社区组件:https://github.com/glanceapp/community-widgets
- Compose 模板仓库:https://github.com/glanceapp/docker-compose-template
- Discord:https://discord.com/invite/7KQ7Xa9kJd
四、环境要求
| 项目 | 要求 |
|---|---|
| 系统 | Linux / macOS / Windows 均可(二进制跨平台) |
| 容器方式 | Docker 20.10+、Compose v2 |
| 二进制方式 | 无需额外运行时(Go 静态编译) |
| 内存 | 官方未标下限,实测 64MB 级别的容器内存足够 |
| 磁盘 | 二进制 < 20MB,容器镜像同样很小 |
| 端口 | 容器内 8080 |
| 配置文件 | glance.yml,必须存在,否则起不来 |
两个额外注意点:
- 它需要外网。所有组件的数据都是运行时去拉的,纯内网环境只能看服务器指标和容器状态
- 如果你用了 Pi-Hole / AdGuard Home,要留意它们的 DNS 查询频率限制,Glance 组件一多很容易超限(官方把它列为最常见的超时原因)
五、部署步骤
官方给了三种安装方式,这里走前两种(第三种是第三方渠道,不展开)。
方式一:官方 compose 模板(README 推荐)
官方推荐的是「用现成的目录结构」,一条命令把模板拉下来:
mkdir glance && cd glance && curl -sL https://github.com/glanceapp/docker-compose-template/archive/refs/heads/main.tar.gz | tar -xzf - --strip-components 2
执行完目录里会有这些文件,按官方说明逐个改:
docker-compose.yml—— 改端口、卷、容器相关配置config/home.yml—— 首页有哪些组件、怎么排版config/glance.yml—— 主题、额外页面.env—— 配置文件里能引用的环境变量assets/user.css—— 自定义 CSS
改完启动:
docker compose up -d
看日志:
docker compose logs
这条路的优点是目录结构、示例配置都是现成的,适合想直接上手调布局的人。
方式二:手写 compose(结构最清楚)
先建 compose 文件:
services:
glance:
container_name: glance
image: glanceapp/glance
restart: unless-stopped
volumes:
- ./config:/app/config
ports:
- 8080:8080
再拉一份官方示例配置:
mkdir config && wget -O config/glance.yml https://raw.githubusercontent.com/glanceapp/glance/refs/heads/main/docs/glance.yml
启动:
docker compose up -d
出问题看日志:
docker logs glance
这份 compose 与官方 README 完全一致。注意 ./config 必须存在且里面有 glance.yml,容器启动时找不到配置会直接退出。
方式三:二进制(不用 Docker)
官方给了 Linux 的做法:从 releases 页面下二进制,放到 /opt/glance/,用 systemd 托管。默认会在二进制所在目录找 glance.yml,要指定别的路径用 --config:
/opt/glance/glance --config /etc/glance.yml
拉一份起步模板:
wget https://raw.githubusercontent.com/glanceapp/glance/refs/heads/main/docs/glance.yml
写个 systemd 单元:
[Unit]
Description=Glance Dashboard
After=network.target
[Service]
Type=simple
ExecStart=/opt/glance/glance --config /etc/glance.yml
Restart=always
RestartSec=5
User=root
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable --now glance
systemctl status glance
加一层反代(可选但推荐)
Glance 本身没有账号体系,默认谁都能看。放到公网一定要加认证。Caddy 版本:
glance.your-domain.tld {
reverse_proxy 127.0.0.1:8080
}
要加密码保护,用 Caddy 的 basic auth:
caddy hash-password --plaintext 'your-password'
glance.your-domain.tld {
basic_auth {
admin $2a$14$替换成上面命令输出的哈希
}
reverse_proxy 127.0.0.1:8080
}
六、配置参数详解
glance.yml 的结构是三层:页面(pages)→ 分组(groups / columns)→ 组件(widgets)。看懂这三层,剩下都是查文档。
整体骨架
pages:
- name: Home
columns:
- size: small
widgets:
- type: clock
- type: weather
location: Beijing, China
units: metric
hour-format: 24h
- size: full
widgets:
- type: rss
feeds:
- url: https://example.com/feed.xml
三个要点:
pages是顶层,可以有多个页面,每个页面在导航栏是一个 tabcolumns决定列宽,常用small/fullwidgets里每个type对应一个组件
常用组件参数
RSS
- type: rss
title: 我关注的博客
limit: 10
collapse-after: 3
cache: 15m
feeds:
- url: https://example.com/feed.xml
- url: https://another.com/rss
limit 控制条数,collapse-after 控制默认折叠到第几条,cache 控制缓存时长(15m、1h、1d 这种写法)。
服务器指标
- type: server-stats
servers:
- type: local
Docker 容器状态
- type: docker-containers
hide: []
show-mouse-positions: true
行情
- type: markets
markets:
- symbol: BTC-USD
name: Bitcoin
- symbol: AAPL
name: Apple
GitHub Release 追踪(官方示例里有,很适合追自托管项目更新)
- type: releases
cache: 1d
repositories:
- glanceapp/glance
- immich-app/immich
天气
- type: weather
location: London, United Kingdom
units: metric
hour-format: 12h
通用参数
几乎所有组件都支持这组参数:
| 参数 | 说明 |
|---|---|
title |
覆盖组件标题,官方 FAQ 明确说所有组件都能改 |
cache |
缓存时长,如 15m / 1h / 1d |
hide-header |
隐藏组件顶栏 |
css-class |
附加自定义 CSS 类 |
环境变量
compose 模板里带了 .env,配置文件里可以用环境变量替换敏感信息。比如把 API key 放 .env,glance.yml 里引用变量名,这样配置文件可以安全地提交到 Git。
七、启动与运维
# 启停
docker compose up -d
docker compose restart
docker compose down
# 日志
docker compose logs -f --tail=100
# 资源占用(Glance 通常很小)
docker stats glance
# 改完配置后必须重启才生效
docker compose restart
关键运维点:改配置必须重启。Glance 没有热加载,glance.yml 改完 restart 一下才生效。重启大约 1 秒,影响很小。
备份只有一个东西要备:config/ 目录。
tar czf glance-config-$(date +%F).tar.gz config/
关于更新的期望管理:官方 FAQ 说得很直白——页面信息不会自动更新,需要刷新页面;组件也不会在后台定时拉数据,只在页面加载时拉一次然后缓存。所以别指望它像监控大屏那样秒级刷新。
八、实操验证
1. 容器是否在跑
docker ps --filter name=glance --format '{{.Status}}'
应该是 Up X seconds。如果反复重启,直接看 docker logs glance,九成是 glance.yml 格式错误。
2. 本机端口
curl -I http://127.0.0.1:8080
HTTP/1.1 200 OK。
3. 页面能否打开
浏览器访问 http://服务器IP:8080,应该看到官方示例配置渲染出的页面——时钟、天气、RSS、视频、行情这些卡片。
4. 改一个配置验证热改流程
编辑 config/glance.yml,把某个组件的 title 改掉:
- type: rss
title: 我的订阅源
docker compose restart
刷新页面看到标题变了,说明配置挂载和重启链路是通的。
5. 验证数据源
点开 RSS 卡片看有没有条目。如果显示空,先点进去看是源本身没内容,还是容器拉不到外网:
docker exec glance wget -qO- https://example.com/feed.xml | head
九、故障排查
Glance 的官方 README 有一个专门的 Common issues 段落,这几条是最常见的坑,直接照着官方结论排查最省时间。
请求超时(Requests timing out)
官方原话:最常见的原因是用了 Pi-Hole、AdGuard Home 这类去广告 DNS,它们默认的查询频率限制比较低,而 Glance 一个页面上组件一多,很容易超限。
解决办法:去你的 DNS 服务设置里把频率限制调高。
如果用的是 Podman,官方说极少数情况下的超时是这个原因,可以在 docker-compose.yml 末尾加:
networks:
podman:
external: true
行情、书签等组件布局错乱
官方结论:几乎都是浏览器扩展 Dark Reader 导致的。处理方法是在 Glance 域名下关掉深色模式。
报错 cannot unmarshal !!map into []glance.page
官方解释:glance.yml 里已经有 pages 键了,而你 include 进来的页面里又写了一个 pages。解决办法是把被 include 页面顶部的 pages 键删掉。
容器起来就退出
docker logs glance
如果是 no such file or directory 指向 glance.yml,说明 ./config/glance.yml 不存在或路径不对。确认:
ls -l config/glance.yml
YAML 缩进报错
YAML 对缩进极其敏感,用了 Tab 就会报错。统一用两个空格。校验一下:
docker run --rm -v $(pwd)/config:/c python:3-alpine python -c "import yaml,sys; yaml.safe_load(open('/c/glance.yml'))" && echo OK
页面能开但组件全是空的
按顺序查:容器能否访问外网(docker exec glance wget -qO- https://www.google.com)、对应数据源是否还活着、以及是不是被 DNS 限速了。
十、升级、回滚与卸载
升级
镜像没有固定版本号标签,升级就是拉最新:
cd glance
docker compose pull
docker compose up -d
配置在宿主机 config/ 里,升级不会动它。但大版本可能改配置字段名,升级前备份 config/,升级后如果页面报错,先对照官方 docs/glance.yml 看字段有没有变。
回滚
要回到具体版本,把 compose 里的镜像改成带版本号的:
image: glanceapp/glance:v0.8.4
然后 docker compose up -d。版本号从 https://github.com/glanceapp/glance/releases 查。同时把备份的 config/ 还原。
卸载
cd glance
docker compose down
docker rmi glanceapp/glance
rm -rf glance
Glance 不存任何业务数据,config/ 删掉就彻底干净了。二进制方式的话:
systemctl disable --now glance
rm -rf /opt/glance /etc/glance.yml /etc/systemd/system/glance.service
systemctl daemon-reload
十一、商用许可
Glance 使用 AGPL-3.0。
要点:
- 可以商用,公司内部拿来当团队首页、当运维面板都没问题,不需要付费
- 可以修改,但如果你把改过的版本作为网络服务提供给外部用户,必须公开修改后的完整源码。这是 AGPL 与 GPL 的核心差异——GPL 只管分发,AGPL 连 SaaS 场景也管
- 可以分发,需附带许可证与源码
- 不提供担保
实际判断标准很简单:
- 自己部署、自己看、团队内部用 → 随便用,AGPL 对你没有额外负担
- 改完代码包装成产品卖给客户,或者做成对外 SaaS → 必须开源你的修改
如果你只是想要一个好看的聚合首页,Glance 的许可完全不会妨碍你。