Why a self-hosted dashboard on your VPS
A multi-application VPS without a central page is infrastructure managed blind. You memorize each port (http://your-domain.com:3001, :8080, :9000…), you waste time finding the interface of a service stopped three weeks ago, and you have no consolidated view of your containers' status.
A self-hosted dashboard solves this without weighing down your infrastructure: a single page, accessible over HTTPS behind your reverse proxy, aggregating status, shortcuts and metrics. You share no data with a third-party service, and you pay no extra subscription.
Concrete use cases
- Browser home page pointing to your own VPS: all your services one click away.
- Real-time status view of your Docker containers without opening Portainer or Dozzle.
- RSS feed aggregation and tech news (Hacker News, Reddit, GitHub releases) on the same screen as your services.
- Centralized access for a team or agency sharing a common VPS.
- Start page for your homelab or development infrastructure.
- Lightweight monitoring without deploying a full Grafana/Prometheus stack.
Homarr: full-featured dashboard with a graphical interface
Homarr is a self-hosted Next.js dashboard with a fully graphical configuration interface — you drag and drop tiles, configure Docker integrations, Sonarr, Radarr, Jellyfin or any service with an API. It runs in a single Docker container (image ghcr.io/homarr-labs/homarr) and persists its configuration on a volume.
Requirements: a VPS with at least 512 MB of RAM available after your other containers, Docker and Docker Compose installed, and a domain name or subdomain pointed to your IP. Expect 150 to 250 MB of RAM at rest depending on active integrations.
Deploy Homarr with Docker Compose
Create the directory and Compose file
On your VPS, create a dedicated directory and a
docker-compose.ymlfile:mkdir -p /opt/homarr && cd /opt/homarrContent of the
docker-compose.ymlfile:services: homarr: image: ghcr.io/homarr-labs/homarr:latest container_name: homarr restart: unless-stopped volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - ./appdata:/appdata environment: - SECRET_ENCRYPTION_KEY=your-random-32-char-key ports: - "7575:7575"SECRET_ENCRYPTION_KEYis required: Homarr encrypts its integration secrets (API tokens, passwords) with this key. Generate one withopenssl rand -hex 32.Generate the encryption key
Homarr requires a 64-character hexadecimal key:
openssl rand -hex 32Copy the value into
SECRET_ENCRYPTION_KEYin the Compose file. Without this variable, the container refuses to start.Start the container
docker compose up -dHomarr is accessible at
http://your-domain.com:7575. On first access, create your administrator account. Initial configuration (tiles, theme, integrations) is done entirely from the web interface.Configure the Docker integration
The Docker socket (
/var/run/docker.sock) is mounted read-only. In the Homarr interface, go to Settings → Integrations and add a Docker integration pointing tounix:///var/run/docker.sock. Homarr will automatically display the status (running/stopped) of your containers on the associated tiles.Configure Traefik as reverse proxy
To expose Homarr over HTTPS, add these labels to your service in the Compose file:
labels: - "traefik.enable=true" - "traefik.http.routers.homarr.rule=Host(`dashboard.your-domain.com`)" - "traefik.http.routers.homarr.entrypoints=websecure" - "traefik.http.routers.homarr.tls.certresolver=letsencrypt" - "traefik.http.services.homarr.loadbalancer.server.port=7575"Remove the
portsblock if you expose only via Traefik. See the article Deploy with Traefik for the full configuration.nginx alternative
If you use nginx, create a vhost
/etc/nginx/sites-available/homarr.conf:server { listen 443 ssl; server_name dashboard.your-domain.com; ssl_certificate /etc/letsencrypt/live/dashboard.your-domain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/dashboard.your-domain.com/privkey.pem; location / { proxy_pass http://127.0.0.1:7575; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }Let's Encrypt certificate via
certbot --nginx -d dashboard.your-domain.com.
Glance: a Go binary, a YAML config, no database
Glance is at the opposite end of the complexity spectrum from Homarr. It is a static Go binary: no Node.js, no database, no configuration interface. Everything is declared in a glance.yml file. It consumes less than 50 MB of RAM at rest, making it the natural choice for a tight VPS or a server where every megabyte counts.
License: AGPL-3.0 (same as Homarr). Source code on GitHub.
Deploy Glance with Docker
Create the directory and configuration file
mkdir -p /opt/glance && cd /opt/glanceCreate a minimal
glance.ymlfile with a Hacker News widget and a Docker widget:server: host: 0.0.0.0 port: 8080 pages: - name: Home columns: - size: full widgets: - type: hacker-news title: Hacker News - size: small widgets: - type: docker-containers title: Containers collapsed-by-default: falseGlance exposes port 8080 by default.
Launch with Docker Compose
Create a
docker-compose.ymlfile:services: glance: image: glanceapp/glance:latest container_name: glance restart: unless-stopped volumes: - ./glance.yml:/app/glance.yml:ro - /var/run/docker.sock:/var/run/docker.sock:ro ports: - "8080:8080"Start with:
docker compose up -dGlance is accessible at
http://your-domain.com:8080.Add a weather widget
The
weatherwidget is one of the simplest to configure — it only requires a location:- type: weather title: Weather location: London, UK units: metric hour-format: 24hAdd this block in the
widgetssection of your chosen column.Configure the reverse proxy for Glance
With Traefik, add in your
docker-compose.yml:labels: - "traefik.enable=true" - "traefik.http.routers.glance.rule=Host(`glance.your-domain.com`)" - "traefik.http.routers.glance.entrypoints=websecure" - "traefik.http.routers.glance.tls.certresolver=letsencrypt" - "traefik.http.services.glance.loadbalancer.server.port=8080"With nginx, same structure as Homarr, replacing the port with
8080.Hot reload of configuration
Glance monitors its configuration file and reloads automatically when you modify it. No need to restart the container after each widget addition —
docker logs glance -fwill display theConfig reloadedline after a few seconds.
Homarr vs Glance: comparison table
Scroll the table
| Criterion | Homarr | Glance |
|---|---|---|
| RAM at rest | 150 – 250 MB | < 50 MB |
| Configuration | Drag & drop graphical interface | YAML file only |
| Database | Embedded SQLite | None |
| Available widgets | Integrations (Sonarr, Jellyfin, Docker…) + free tiles | RSS, Hacker News, weather, Docker, GitHub, calendar… |
| Update | `docker compose pull && docker compose up -d` | `docker compose pull && docker compose up -d` |
| License | AGPL-3.0 | AGPL-3.0 |
| Ideal for | Rich infrastructure, daily use, team sharing | Lightweight VPS, minimalist homelabs, quick overview |
Exposing over HTTPS with a reverse proxy
Both tools listen on HTTP locally (7575 for Homarr, 8080 for Glance). Exposing a dashboard directly to the Internet without TLS means transmitting your integration tokens and sessions in plain text.
Two common options:
Traefik — the recommended option if you already have Traefik on your VPS. Labels are sufficient (examples above). Traefik requests and renews Let's Encrypt certificates automatically via ACME DNS-01 or HTTP-01. See the article Deploy with Traefik for the letsencrypt resolver configuration.
nginx — the natural option if your VPS already runs nginx. The proxy_pass http://127.0.0.1:<port> vhost structure is identical for both tools; only the port changes.
Hardening: restrict access to your dashboard
A self-hosted dashboard exposes your internal services. A few precautions:
Homarr authentication: enable built-in authentication on first login. Do not leave the dashboard open without a password, even behind an obscure subdomain.
Glance: does not offer native authentication. Protect it with a Traefik middleware (BasicAuth or ForwardAuth) or via nginx auth_basic before exposing it publicly.
Dedicated Docker network: create an internal: true network for services that do not need external access, and connect only Homarr or Glance to the Traefik network.
Read-only Docker socket: both tools mount /var/run/docker.sock — mount it as :ro (read-only) as shown in the examples above. A compromised container cannot launch new containers via the socket.
Troubleshooting: common errors
Homarr refuses to start — SECRET_ENCRYPTION_KEY missing: the environment variable is missing or empty. Generate a key with openssl rand -hex 32 and add it to the Compose file.
Homarr shows "Docker integration error": verify that /var/run/docker.sock is mounted in the container (docker inspect homarr | grep docker.sock) and that the socket is readable by the user running Docker.
Glance does not load the docker-containers widget: the Docker socket is not mounted or the Docker service is not accessible from the container. Add the volume /var/run/docker.sock:/var/run/docker.sock:ro to the Compose file.
Glance shows a blank screen: your glance.yml has a YAML syntax error (indentation, tab instead of spaces). Check with docker logs glance — the error message indicates the exact line.
502 Bad Gateway behind nginx/Traefik: the container is not running or the port does not match. Check with docker ps | grep homarr or docker ps | grep glance, and make sure the port in your reverse proxy matches the one exposed (7575 or 8080).
Which tool to choose?
Choose Homarr if you have multiple services with APIs (Sonarr, Radarr, Jellyfin, Pi-hole…), if you prefer configuring via a graphical interface, or if you share your dashboard with others. Budget an extra 200 MB of RAM in your container allocation.
Choose Glance if your VPS is tight on memory, if you are comfortable with YAML, or if you want a tool that starts in seconds and consumes the minimum. Configuration versioned in a text file is also an advantage for infrastructure-as-code managed environments.
Both coexist without issue on the same VPS if you have the RAM — Homarr as the main dashboard, Glance as a quick side view.