Skip to main content

Open-source alternatives guide

How to Self-Host Homepage 2026

Self-host Homepage for a self-hosted services dashboard in 2026. Apache 2.0, ~19K stars — app launcher with live service stats, Docker integration, widgets.

·OSSAlt Team
Share:

TL;DR

Homepage (Apache 2.0, ~19K GitHub stars, Next.js) is the most feature-rich self-hosted dashboard for your homelab or server — a central launcher for all your self-hosted apps with live service status, Docker container stats, and over 100 service integrations. One glance shows: is Plex running? What's the Sonarr queue? How loaded is my server? Compare: Dashy (MIT, ~17K stars) is more visual/customizable; Heimdall (MIT, ~7K stars) is simpler; Homepage is the middle ground with the best widget ecosystem.

Key Takeaways

  • Homepage: Apache 2.0, ~19K stars — 100+ service widgets, Docker auto-discovery
  • Live stats: Real-time data from Arr apps, Proxmox, PiHole, Grafana, and more
  • Docker integration: Auto-detect containers and show CPU/RAM usage
  • YAML config: All configuration in YAML files — version-controllable
  • Fast: Prerendered Next.js app, loads in <200ms
  • No database: Pure YAML config, nothing stored

Dashboard Alternatives Comparison

AppLicenseStarsConfigDocker IntegrationWidgets
HomepageApache 2.0~19KYAMLAuto-discover100+
DashyMIT~17KYAMLYes50+
HeimdallMIT~7KWeb UINoBasic
OrganizrUNLICENSE~5KWeb UINoMany
DasherrMIT~500YAMLYesBasic

Part 1: Docker Setup

# docker-compose.yml
services:
  homepage:
    image: ghcr.io/gethomepage/homepage:latest
    container_name: homepage
    restart: unless-stopped
    ports:
      - "3000:3000"
    volumes:
      - ./config:/app/config      # YAML config files
      - /var/run/docker.sock:/var/run/docker.sock:ro    # For Docker integration
    environment:
      PUID: 1000
      PGID: 1000
mkdir config
docker compose up -d

Visit http://your-server:3000.

Part 2: HTTPS with Caddy

home.yourdomain.com {
    reverse_proxy localhost:3000
}

Part 3: Core Configuration Files

Homepage uses 5 YAML files in ./config/:

# config/services.yaml
- Media:
    - Jellyfin:
        href: https://media.yourdomain.com
        description: Media Server
        icon: jellyfin.png
        widget:
          type: jellyfin
          url: http://jellyfin:8096
          key: your-api-key
    - Sonarr:
        href: https://sonarr.yourdomain.com
        icon: sonarr.png
        widget:
          type: sonarr
          url: http://sonarr:8989
          key: your-sonarr-api-key

- Infrastructure:
    - Portainer:
        href: https://portainer.yourdomain.com
        icon: portainer.png
        widget:
          type: portainer
          url: http://portainer:9000
          env: 1
          key: your-portainer-api-key
    - Proxmox:
        href: https://pve.yourdomain.com:8006
        icon: proxmox.png
        widget:
          type: proxmox
          url: https://pve.yourdomain.com:8006
          username: api@pve!homepage
          password: your-token-secret
    - Pi-hole:
        href: http://pihole.lan/admin
        icon: pi-hole.png
        widget:
          type: pihole
          url: http://pihole.lan
          key: your-pihole-api-key

- Monitoring:
    - Netdata:
        href: https://metrics.yourdomain.com
        icon: netdata.png
    - Grafana:
        href: https://grafana.yourdomain.com
        icon: grafana.png
        widget:
          type: grafana
          url: http://grafana:3000
          username: admin
          password: your-grafana-password

widgets.yaml — Top Bar Widgets

# config/widgets.yaml
- logo:
    icon: /icons/logo.png

- greeting:
    text_size: xl
    text: "Good $time, $name!"

- datetime:
    text_size: xl
    format:
      dateStyle: long
      timeStyle: short
      hourCycle: h23

- resources:
    cpu: true
    memory: true
    disk: /
    diskUnits: gigabytes
    expanded: true
    label: server

- search:
    provider: duckduckgo
    target: _blank

- openmeteo:
    label: Home
    latitude: 37.7749
    longitude: -122.4194
    units: imperial
    cache: 5

- unifi_console:
    url: https://unifi.yourdomain.com
    username: readonly
    password: readonly-password
# config/bookmarks.yaml
- Developer:
    - GitHub:
        - href: https://github.com
    - Documentation:
        - href: https://docs.yourdomain.com

- Social:
    - Reddit:
        - href: https://www.reddit.com/r/selfhosted/
    - HackerNews:
        - href: https://news.ycombinator.com

settings.yaml — Global Settings

# config/settings.yaml
title: My Homelab
favicon: /icons/favicon.png
theme: dark
color: slate

background:
  image: /images/background.jpg
  blur: sm
  opacity: 50

layout:
  Media:
    icon: mdi-television-play
    columns: 3
    style: row
  Infrastructure:
    icon: mdi-server
    columns: 4

headerStyle: boxed
statusStyle: dot

providers:
  openweathermap: your-owm-api-key

docker.yaml — Docker Integration

# config/docker.yaml
my-server:
  socket: /var/run/docker.sock

Part 4: Docker Auto-Discovery

Homepage can auto-discover running containers via labels:

# In any docker-compose.yml service:
services:
  jellyfin:
    labels:
      - "homepage.group=Media"
      - "homepage.name=Jellyfin"
      - "homepage.icon=jellyfin.png"
      - "homepage.href=https://media.yourdomain.com"
      - "homepage.description=Media Server"
      - "homepage.widget.type=jellyfin"
      - "homepage.widget.url=http://jellyfin:8096"
      - "homepage.widget.key=your-api-key"

When Homepage detects these labels, it automatically adds the service to the dashboard without modifying services.yaml.

Part 5: Available Widgets

Over 100 service widgets with live data:

CategoryWidgets
MediaJellyfin, Plex, Emby, Sonarr, Radarr, Lidarr, Readarr, Bazarr, Overseerr, Jellyseerr
DownloadqBittorrent, Transmission, Deluge, NZBGet, SABnzbd, Prowlarr
NetworkingPi-hole, AdGuard Home, Unifi, OPNsense, pfSense, Traefik
InfrastructurePortainer, Proxmox, Netdata, Grafana, Uptime Kuma, Healthchecks.io
Home AutomationHome Assistant, Node-RED
SystemResources (CPU/RAM/Disk), Glances
FinanceActual Budget, CoinGecko
MiscNextcloud, Gitea, Miniflux, Calibre

Part 6: Custom Icons

Homepage has a built-in icon library (many popular self-hosted apps). For custom icons:

# Place icons in config/icons/ directory
- My App:
    icon: /icons/my-app.png
    # Or use Material Design Icons:
    icon: mdi-server-network
    # Or use Simple Icons:
    icon: si-github

Part 7: Status Indicators

Each service shows a colored status dot:

  • Green: Service responding (HTTP 200)
  • Yellow: Service responding but degraded
  • Red: Service unreachable
# Enable status checking per service:
- Vaultwarden:
    href: https://vault.yourdomain.com
    ping: https://vault.yourdomain.com/alive   # Custom health endpoint
    # Or just use the href for status check

Maintenance

# Update Homepage:
docker compose pull
docker compose up -d

# Logs:
docker compose logs -f homepage

# Validate YAML:
docker exec homepage node -e "
  const fs = require('fs');
  const yaml = require('js-yaml');
  ['services','widgets','settings','bookmarks','docker'].forEach(f => {
    try { yaml.load(fs.readFileSync(\`/app/config/\${f}.yaml\`,'utf8')); console.log(\`✓ \${f}.yaml\`); }
    catch(e) { console.log(\`✗ \${f}.yaml: \${e.message}\`); }
  });
"

# Config files are just YAML — version control them:
cd ./config && git init && git add . && git commit -m "initial homepage config"

Why Self-Host Homepage

The pitch for a self-hosted dashboard is simple: when you're running 10, 20, or 30 self-hosted services, you need a single place to see them all. Without a dashboard, you're keeping a mental map of ports, subdomains, and service states. Homepage replaces that mental overhead with a visual interface that shows you exactly what's running, what's down, and what's queued.

Commercial dashboard alternatives don't really exist at Homepage's feature level — this is a category where open source wins comprehensively. The closest SaaS equivalent would be something like Grafana Cloud for monitoring plus a custom internal tools page, easily running $50+/month. Homepage is free and does what matters: show your services and their live status.

The widget ecosystem is where Homepage genuinely shines. Most dashboard tools show static links with a colored dot (up/down). Homepage shows you the Sonarr queue count, Radarr upcoming releases, Pi-hole query statistics, Proxmox CPU and memory usage, your Netdata system metrics, Uptime Kuma status, and your Unifi client count — all live, all on one page. This transforms the dashboard from a glorified bookmark manager into actual operational visibility.

Configuration as YAML files is an underrated feature. Every service, widget, and setting is stored in plain text files that you can version-control with git. Your entire homelab dashboard configuration lives in a git repository — you can diff changes, roll back mistakes, and recreate your exact setup on a new server in minutes. Compare this to web UI-based tools like Heimdall where your configuration is locked in a database.

When NOT to self-host Homepage: Homepage is a display tool, not a control plane — you can't manage or restart services from it. If you need active management capabilities, Portainer or a proper monitoring stack (Prometheus + Grafana) serves better. Homepage also requires maintaining YAML files, which can get complex with 30+ services. If YAML configuration feels like overhead, Heimdall's web UI approach may be preferable.

Prerequisites

Homepage is one of the least demanding self-hosted applications in the ecosystem. Its read-only nature (it only reads from Docker and service APIs) means there's very little that can go wrong.

Server specs: 256MB RAM and half a vCPU is genuinely sufficient. Homepage is a prerendered Next.js application — most of the rendering work is done at build time, and each page load is fast. Even a Raspberry Pi 3B can run Homepage without issues. It can comfortably share a VPS with other services. See our VPS comparison for self-hosters to find the right fit — Homepage is best co-located on a VPS you're already using.

Operating system: Ubuntu 22.04 LTS for Docker support. If you're running Homepage on a Raspberry Pi for a home network dashboard, Raspberry Pi OS (64-bit) also works well.

Docker socket access: For Docker integration (showing container stats and auto-discovery), Homepage mounts /var/run/docker.sock read-only. This is safe — Homepage only reads container metadata, never controls them. If you're on a managed hosting environment where Docker socket access isn't available, Homepage still works as a static bookmark launcher without the Docker features.

Service API keys: Each widget you configure needs an API key from the corresponding service. Plan ahead — you'll need to generate API keys from Sonarr, Radarr, Portainer, Grafana, etc. before Homepage can show live data. Most services generate API keys in Settings → API or similar.

Skill level: Beginner. YAML editing is the primary skill required. Start with a simple services.yaml with a few links and expand from there.

Production Security Hardening

Homepage reads from your infrastructure — Docker stats, service APIs, Proxmox credentials, Pi-hole. Its config files contain API keys and potentially passwords for your other services. Securing Homepage protects all of those credentials.

Firewall (UFW): Never expose port 3000 directly. Route everything through your reverse proxy.

sudo ufw default deny incoming
sudo ufw allow ssh
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

Add authentication to your reverse proxy: Homepage has no built-in authentication. Anyone who reaches your Homepage URL has full visibility into your infrastructure status and links. Use Caddy with basic auth or forward auth to an identity provider:

home.yourdomain.com {
    basicauth {
        admin JDJhJDE0JHNvbWVoYXNoZWRwYXNzd29yZA==
    }
    reverse_proxy localhost:3000
}

Secrets management: Homepage config files contain API keys for Sonarr, Portainer, Grafana, and other services. These files should be in a private git repository (not public GitHub) and should never be shared. Consider using Homepage's environment variable support to keep sensitive values out of YAML:

# services.yaml - reference env vars:
widget:
  key: {{HOMEPAGE_VAR_SONARR_KEY}}
# .env (add to .gitignore)
HOMEPAGE_VAR_SONARR_KEY=your-sonarr-api-key

Read-only Docker socket: Mount /var/run/docker.sock:ro (read-only) as shown in the Docker Compose config. This prevents Homepage from ever accidentally modifying Docker resources even if the application were compromised.

Automatic security updates:

sudo apt install unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades

Follow the self-hosting security checklist for the full picture. And back up your config directory — it contains your entire dashboard configuration. See automated server backups with restic for a simple automated approach.

Organizing Your Dashboard Effectively

A poorly organized Homepage dashboard is more confusing than useful. The structure you establish when you first set it up tends to stick, so it's worth thinking through the organization before you start adding services.

Group services by functional area rather than by how they're deployed. "Media" and "Monitoring" and "Infrastructure" make sense as categories. "Docker containers" and "VMs" do not — that's an implementation detail, not a mental model. Users of your dashboard shouldn't need to know the deployment topology to find what they're looking for.

Limit each group to 4-6 services. Homepage renders groups in columns, and a group with 15 services becomes a wall of icons that requires scanning. If a functional area has more than 6 services, split it. "Media" can become "Media Servers" and "Media Management" — Jellyfin and Plex in one group, Sonarr/Radarr/Lidarr in another.

Use the description field consistently. A service called "Traefik" with no description requires domain knowledge to understand — not every person who looks at your dashboard knows what Traefik is. "Traefik — reverse proxy and SSL" takes three seconds to read and eliminates confusion. Consistent descriptions also make the dashboard useful as documentation for your homelab setup.

Version-control your config directory from day one. The maintenance command at the end of Part 7 shows how to initialize a git repo in your config directory. Commit changes with meaningful messages: "add Sonarr widget" or "move Pi-hole to Networking group." When you break something with a YAML edit, git diff immediately shows what changed. When your server dies and you're rebuilding, git clone restores your entire dashboard configuration in seconds.

Use the Docker label approach (Part 4) for services you're likely to add, remove, or reconfigure frequently. This is especially useful for development or staging services that come and go. For stable production services, explicit services.yaml entries give you more control over layout and ordering.

The statusStyle: dot setting in settings.yaml shows each service's status as a colored dot rather than a text label, keeping the interface clean. Combined with a dark theme and a background image with moderate blur, Homepage creates a dashboard that's both functional and visually polished enough to leave on a second monitor.

Troubleshooting Common Issues

Dashboard loads but widgets show "Error" or no data

Widget errors mean Homepage can't reach the service API. Most common causes: the service URL in services.yaml uses localhost (wrong — use the Docker service name or actual IP/domain), the API key is incorrect or expired, or the service requires HTTPS but you specified HTTP. Click the error icon in Homepage to see the specific error message. Test the API endpoint directly with curl from the Homepage container: docker exec homepage curl http://sonarr:8989/api/v3/system/status?apiKey=YOUR_KEY.

Docker integration shows no containers

Check that /var/run/docker.sock is mounted: docker inspect homepage | grep docker.sock. If missing, it means the volume mapping in docker-compose.yml is wrong. Also verify docker.yaml is configured with the correct socket path. On some systems, the Docker socket is at a non-standard location.

YAML validation errors after editing config

Homepage is strict about YAML syntax. Use the validation command in the Maintenance section to identify which file has an error and where. Common mistakes: inconsistent indentation (tabs vs spaces — YAML requires spaces), missing quotes around values containing special characters, or incorrect list formatting. The error message from the validator usually points to the exact line.

Status dots all red even though services are running

Homepage pings the href URL to determine service status. If your services are on internal IPs or private domains that Homepage can't resolve from inside the container, all checks will fail. Make sure Homepage can reach the services — either by using Docker service names (if on the same network), internal IPs, or adding Homepage to the same Docker network as your other services.

Homepage very slow to load or widgets take a long time to populate

Homepage loads widget data in parallel on each page request. If you have many widgets pointing to slow or unreachable services, the page hangs waiting for timeouts. Identify the slow widget by removing them one by one. You can also add timeout to individual widgets: timeout: 2000 (milliseconds) to fail fast.

See the best open source developer tools for more self-hosted tooling that pairs well with a Homepage dashboard.

See all open source homelab and infrastructure tools at OSSAlt.com/categories/homelab.

The SaaS-to-Self-Hosted Migration Guide (Free PDF)

Step-by-step: infrastructure setup, data migration, backups, and security for 15+ common SaaS replacements. Used by 300+ developers.

Join 300+ self-hosters. Unsubscribe in one click.