Every morning goes the same way: open the RSS reader, then Hacker News, then a couple of subreddits, then the weather, then a quick look at whether the home server is still alive. Five tabs to answer one question: what's new?
Glance collapses all of that into one page. It's a self-hosted dashboard that pulls your feeds, news, videos, weather, markets and server status into a single, fast, good-looking start page. You describe the page in one YAML file and Glance does the rest. It runs as a single small binary or a Docker container, and it's quietly become one of the most popular self-hosted projects on GitHub, at over 35,000 stars.
What it is (and isn't)
Glance is a reading dashboard. Its job is to put the things you check every day in one place, laid out in columns, so one glance (hence the name) tells you what changed. It's written in Go, licensed AGPL-3.0, and the whole thing ships as a single binary under 20 MB with few dependencies.
It is not a live monitoring system. This is the single most important thing to understand before you set it up:
- Glance fetches data when you load the page, then caches it. Nothing runs in the background.
- The page doesn't update itself. A refresh pulls fresh data, once the cache for that widget has expired.
- Clocks and relative timestamps ("3h ago") do tick on their own, but feeds and stats don't.
That design is why it's so light. There's no database, no worker process, no polling loop eating CPU at 3 a.m. If you want alerts at 3 a.m., pair it with something like Uptime Kuma. If you want a start page that loads in about a second, this is it.
The widgets
Everything on a Glance page is a widget. The built-in set covers most of what a self-hoster checks in a day:
FEEDS & NEWS
rss RSS and Atom feeds, several display styles
hacker-news Hacker News front page
lobsters Lobsters front page
reddit any subreddit, with optional thumbnails
videos latest uploads from YouTube channels
twitch-channels who's live
releases new releases from GitHub, GitLab, Docker Hub
HOMELAB
monitor is each service up, and how fast did it answer
docker-containers status of your containers
server-stats CPU, memory and disk usage
dns-stats AdGuard Home, Pi-hole or Technitium stats
repository stars, issues and PRs for a GitHub repo
EVERYDAY
weather, calendar, clock, markets, bookmarks, search, to-do
BUILD YOUR OWN
custom-api fetch any JSON API and render it with a template
extension pull HTML from a URL you control
html, iframe drop in your own markup or embed a page
LAYOUT
group stack widgets as tabs
split-column put widgets side by side
Every widget accepts a title to rename it, and most accept a cache duration such as 30m, 12h or 1d. The exceptions are weather and calendar, which update hourly on a fixed schedule.
Install it with Docker
The fastest route is the official compose template, which sets up a sensible folder layout in one command:
mkdir glance && cd glance && curl -sL \
https://github.com/glanceapp/docker-compose-template/archive/refs/heads/main.tar.gz \
| tar -xzf - --strip-components 2
That gives you docker-compose.yml, config/glance.yml and config/home.yml. Edit them, then:
docker compose up -d
If you'd rather build it by hand, the compose file is tiny:
services:
glance:
container_name: glance
image: glanceapp/glance
restart: unless-stopped
volumes:
- ./config:/app/config
ports:
- 8080:8080
Grab the example config to start from, and bring it up:
mkdir config && wget -O config/glance.yml \
https://raw.githubusercontent.com/glanceapp/glance/refs/heads/main/docs/glance.yml
docker compose up -d
# open http://localhost:8080
No Docker? There are precompiled binaries for Linux, Windows and macOS on x86, x86_64, ARM and ARM64. Drop the binary next to a glance.yml and run it. On Linux it's easy to wrap in a systemd service under /opt/glance/. It also builds from source with Go 1.23 or newer: go build -o build/glance .
How the config works
The whole dashboard is one YAML file, and the structure is three levels deep: pages contain columns, and columns contain widgets.
pages:
- name: Home
columns:
- size: small
widgets:
- type: calendar
- size: full
widgets:
- type: hacker-news
- size: small
widgets:
- type: weather
location: London, United Kingdom
Each page becomes a tab across the top, and you can have as many as you like: a Home page, a Homelab page, a Videos page. Columns follow a few strict rules worth knowing up front, because breaking them is the most common first-run error:
- A page has at most three columns.
- It must have one or two
fullcolumns. smallcolumns are a fixed 300px wide, andfullcolumns share whatever's left.- Valid shapes: 1 full, 2 full, 1 full + 2 small, or 2 full + 1 small.
The classic layout is small / full / small: quick-glance stuff on the sides, the main reading feed in the middle.
Hot reload
Save the file and Glance picks up the change immediately, with no restart. If you save a broken config, it keeps running the last good one and logs the error. One catch: a reload clears the widget caches, so if you save twenty times in five minutes you can trip rate limits on sites like Reddit. Batch your edits.
Splitting the file, and keeping secrets out of it
Once the config grows, split it up with $include. That's what the compose template does with home.yml:
pages:
- $include: home.yml
- $include: homelab.yml
Anything sensitive, such as API keys and tokens, can come from environment variables instead of sitting in the file. Glance can also read Docker secrets:
token: ${GITHUB_TOKEN}
password: ${secret:dashboard_password}
A homelab page that earns its tab
Here's where Glance stops being a news reader and becomes genuinely useful for anyone running services at home. A second page, three widgets:
- name: Homelab
columns:
- size: full
widgets:
- type: monitor
cache: 1m
title: Services
sites:
- title: Jellyfin
url: https://jellyfin.yourdomain.com
- title: AdGuard Home
url: https://adguard.yourdomain.com
- type: docker-containers
hide-by-default: false
- size: small
widgets:
- type: server-stats
servers:
- type: local
name: Services
monitor sends a GET request to each URL and shows whether it answered with a 200, plus how many milliseconds it took. server-stats shows CPU, memory and disk for the machine Glance runs on.
docker-containers needs access to the Docker socket, so add it to the Glance service's volumes:
volumes:
- ./config:/app/config
- /var/run/docker.sock:/var/run/docker.sock
Then dress up each container with labels in its own compose file, so it shows a proper name, icon and link:
jellyfin:
image: jellyfin/jellyfin:latest
labels:
glance.name: Jellyfin
glance.icon: si:jellyfin
glance.url: https://jellyfin.yourdomain.com
glance.description: Movies & shows
A word on that socket: mounting docker.sock gives the container control over Docker on the host, which is effectively root. Glance only reads from it, but if you'd rather not hand it the keys, point sock-path at a read-only proxy such as docker-socket-proxy instead.
Build your own widget in five lines
The custom-api widget is the secret weapon. Point it at any JSON endpoint and render the result with a Go template:
- type: custom-api
title: Random Fact
cache: 6h
url: https://uselessfacts.jsph.pl/api/v2/facts/random
template: |
<p class="size-h4">{{ .JSON.String "text" }}</p>
Anything with a JSON API becomes a widget: your router, your Home Assistant, a game server, a package tracker. Before writing your own, check the community-widgets repo. There's a good chance someone already built it.
Theming
Glance themes are a handful of HSL values (hue, saturation, lightness, space-separated, no percent signs). Change three numbers and the whole dashboard follows. Naturally, here's one in this site's colors:
theme:
background-color: 140 30 4
primary-color: 135 100 60
contrast-multiplier: 1.2
presets:
amber-crt:
background-color: 30 30 4
primary-color: 41 100 50
contrast-multiplier: 1.2
Presets show up in a theme picker on the page, so you can switch between phosphor green and amber without touching the file. For deeper changes, custom-css-file loads your own stylesheet, and there's a light: true option if you're that kind of person. The repo's docs/themes.md has a gallery of ready-made themes to copy.
Locking it down
A dashboard that shows your containers and server stats shouldn't be open to the internet. Glance has built-in username and password auth. Generate a secret key and a password hash:
docker run --rm glanceapp/glance secret:make
docker run --rm glanceapp/glance password:hash mysecretpassword
Then add them to the top of glance.yml:
auth:
secret-key: ${GLANCE_SECRET_KEY}
users:
admin:
password-hash: ${GLANCE_ADMIN_HASH}
Even with auth on, the safest setup is to keep Glance on your LAN or behind a VPN like WireGuard or Tailscale. If you do expose it, put it behind a reverse proxy with HTTPS.
Tips from setting it up
- Make it your browser's start page. That's where it pays off. Every new tab is the dashboard.
- Set sensible caches.
1mfor monitors,1hor more for feeds,1dfor releases. Long caches keep page loads fast and keep you clear of rate limits. - Use
groupto save space. Hacker News and Lobsters in one tabbed widget, or three subreddits in another. - Feed it the small web. The rss widget is the heart of Glance. Personal blogs and project feeds are where it shines. This site has a feed too, if you want to give it a test.
- Use the
releaseswidget for update-watching. List the projects you self-host and you'll see new versions the morning they ship.
Verdict
Glance does one thing and does it well: it turns a morning of tab-hopping into a single page that loads in about a second. Setup is a compose file and a YAML file, the resource footprint is close to nothing, and the custom-api widget means it grows with whatever else you run. If you keep a homelab, or just read a lot of feeds, it's one of the easiest self-hosted wins there is.
Start with the GitHub repo and the configuration docs, which cover every widget option in depth. The image is in the downloads directory, and Glance is in the resource index.
End of transmission.