Dashboard beginner ⏱ 20 minutes

Homepage: Your Centralized Homelab Dashboard

Modern dashboard with Docker autodiscovery. 100+ service integrations and extensive customization.

By homelabbing.io • 2025-12-16
#homepage#dashboard#docker#management#monitoring

Homepage is a modern, fully static, fast, and secure application dashboard designed specifically for homelabs and self-hosted environments. With automatic Docker discovery, over 100 service integrations, and extensive customization capabilities, Homepage provides a beautiful centralized hub for managing all your services.

Prerequisites

Before starting this guide, ensure you have:

  • Docker and Docker Compose installed on your system
  • A Linux-based system (Ubuntu, Debian, or compatible distro)
  • Basic understanding of YAML file format
  • Basic familiarity with Docker containers
  • A text editor (VS Code, Nano, or Vim)
  • Access to terminal/SSH on your homelab server
  • At least 2 self-hosted services running in Docker (optional but recommended)

Optional but Helpful:

  • Reverse proxy experience (Nginx, Traefik, or Caddy)
  • Understanding of Docker labels and metadata
  • Knowledge of REST APIs and authentication tokens

Understanding Homepage and Why It Matters

What is Homepage?

Homepage is an open-source, fully static, fast, secure, and highly customizable dashboard that serves as a single pane of glass for managing self-hosted services and applications. Unlike traditional dashboards that require server-side processing, Homepage renders entirely on the client-side, reducing server load and making it suitable for deployment on low-powered hardware like Raspberry Pi.

Key Characteristics:

  • Fully Static: Client-side rendering reduces server CPU usage
  • Fast: Minimal resource consumption, works well on Raspberry Pi
  • Secure: Fully proxied and stateless, designed to run behind a reverse proxy
  • Customizable: YAML-based configuration with support for hundreds of integrations
  • Docker-Native: Built-in Docker support with automatic service discovery

Homepage vs Other Dashboards

Choosing the right dashboard for your homelab depends on your specific needs. Here’s how Homepage compares to alternatives:

FeatureHomepageHeimdallHomarrDashy
Learning CurveMediumEasyEasyHard
ConfigurationYAML/Docker LabelsGUIGUI (Drag & Drop)YAML/GUI
Service Integrations100+Basic20+50+
Docker AutodiscoveryYesNoYesNo
Kubernetes SupportYesNoLimitedNo
AuthenticationReverse Proxy OnlyBuilt-inBuilt-in (Beta)Built-in
CustomizationHighMediumHighVery High
Resource UsageVery LowVery LowLowMedium
Active DevelopmentHighly ActiveStagnantActiveActive

Choose Homepage if:

  • You have 20+ services to manage
  • You use Docker extensively with label support
  • You use Kubernetes
  • You want minimal resource usage
  • You prefer YAML configuration
  • You need extensive service integrations

Real-World Use Cases

Homepage excels in several homelab scenarios:

  1. Homelab Gateway: Serve as the primary landing page when accessing your homelab network
  2. Service Dashboard: Monitor status and access media servers (Plex, Jellyfin), download managers (Radarr, Sonarr), and other services
  3. Infrastructure Monitoring: Display system resources, Docker container stats, and Kubernetes cluster status
  4. Bookmark Hub: Organize links to frequently visited websites alongside service shortcuts
  5. Public-Facing Portal: Share selective service access with family members or team members

Installation and Basic Setup

Prerequisites Check

Before installing Homepage, verify your system is ready:

# Check Docker installation
docker --version

# Check Docker Compose installation
docker-compose --version

# Verify Docker is running
docker ps

# Create configuration directory
mkdir -p ~/homelab/homepage/config
cd ~/homelab/homepage

Docker Compose Setup

Create a docker-compose.yml file in your homepage directory:

version: '3.8'

services:
  homepage:
    image: ghcr.io/gethomepage/homepage:latest
    container_name: homepage
    ports:
      - 3000:3000
    volumes:
      - ./config:/app/config
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      HOMEPAGE_ALLOWED_HOSTS: localhost:3000  # Update with your domain
      PUID: 1000  # Your user ID
      PGID: 1000  # Your group ID
      TZ: America/New_York  # Your timezone
    restart: unless-stopped

Important Configuration Notes:

  • HOMEPAGE_ALLOWED_HOSTS: Update this to match your domain or IP address. For local access, use localhost:3000. For remote access, use your domain like dashboard.example.com.
  • PUID and PGID: Run id in terminal to find your user and group IDs. This ensures Homepage runs with proper permissions.
  • Docker Socket: The /var/run/docker.sock mount enables Docker autodiscovery. This is read-only (:ro) for security.

Starting Homepage for the First Time

Launch the Homepage container:

# Start the container
docker-compose up -d

# Verify it's running
docker ps | grep homepage

# Check logs for any errors
docker logs homepage

# View real-time logs (Ctrl+C to exit)
docker logs -f homepage

Access Homepage in your browser at http://localhost:3000. You should see a default dashboard with no services configured yet.

Configuration Directory Structure

Homepage uses several YAML configuration files, all stored in the config/ directory:

config/
├── settings.yaml          # Global settings, theme, language
├── services.yaml          # Service definitions and widgets
├── bookmarks.yaml         # Bookmark groups and links
├── docker.yaml            # Docker socket connection
├── kubernetes.yaml        # Kubernetes API configuration
└── custom.css             # Custom CSS styling

These files will be automatically created when Homepage first starts. Let’s configure each one.

Configuring Your First Services

Understanding Service Definition

Services in Homepage are defined using YAML syntax. Each service belongs to a group and can optionally include a widget that displays real-time data from the service.

Basic service structure:

- GroupName:
    - ServiceName:
        icon: servicename.svg
        href: http://service-url:port
        description: Brief description

Creating Your First Service Group

Create or edit config/services.yaml:

# Media Services
- Media:
    - Plex:
        icon: plex.svg
        href: http://plex.example.com:32400
        description: Media Server

    - Jellyfin:
        icon: jellyfin.svg
        href: http://jellyfin.example.com:8096
        description: Open Source Media Server

# Download Management
- Downloads:
    - Radarr:
        icon: radarr.svg
        href: http://radarr.example.com:7878
        description: Movie Management

    - Sonarr:
        icon: sonarr.svg
        href: http://sonarr.example.com:8989
        description: TV Series Management

# Administration
- Admin:
    - Proxmox:
        icon: proxmox.svg
        href: https://proxmox.example.com:8006
        description: Virtualization Platform

    - Portainer:
        icon: portainer.svg
        href: http://portainer.example.com:9000
        description: Docker Management

YAML Formatting Tips:

  • Use 2 or 4 spaces for indentation (never tabs)
  • Maintain consistent indentation throughout the file
  • Use colons followed by a space for key-value pairs
  • Strings with special characters should be in quotes

After saving the file, refresh your Homepage dashboard. Your services should now appear organized in groups.

Adding Service Widgets

Widgets display real-time data from your services. To use widgets, you’ll need API keys from each service.

Finding API Keys

Most services store API keys in their settings:

ServiceLocation
PlexSettings → Account → Authorization Token
RadarrSettings → General → API Key
SonarrSettings → General → API Key
JellyfinAdmin Dashboard → API Keys
Home AssistantProfile → Long-lived Access Tokens
Pi-holeSettings → API / Web interface → Show API Token

Configuring Widgets

Update your services.yaml to include widgets:

- Media:
    - Plex:
        icon: plex.svg
        href: https://app.plex.tv
        description: Media Server
        widget:
          type: plex
          url: http://plex.local:32400
          key: YOUR_PLEX_TOKEN_HERE

- Downloads:
    - Radarr:
        icon: radarr.svg
        href: http://radarr.example.com:7878
        description: Movie Management
        widget:
          type: radarr
          url: http://radarr:7878
          key: YOUR_RADARR_API_KEY

    - Sonarr:
        icon: sonarr.svg
        href: http://sonarr.example.com:8989
        description: TV Series Management
        widget:
          type: sonarr
          url: http://sonarr:8989
          key: YOUR_SONARR_API_KEY

- Network:
    - Pi-hole:
        icon: pi-hole.svg
        href: http://pihole.local/admin
        description: DNS Ad Blocking
        widget:
          type: pihole
          url: http://pihole.local
          key: YOUR_PIHOLE_API_KEY

- Infrastructure:
    - Proxmox:
        icon: proxmox.svg
        href: https://proxmox.example.com:8006
        description: Virtualization Platform
        widget:
          type: proxmox
          url: https://proxmox.example.com:8006
          username: api@pam!homepage
          password: YOUR_API_TOKEN
          node: proxmox-node-1

Widget Configuration Notes:

  • type: Must match the service type (see Homepage documentation for all supported types)
  • url: Should be the internal URL accessible from the Homepage container (use container names if on the same Docker network)
  • key/token: The API authentication key
  • username/password: Some services require username/password instead of API keys

Testing Widget Connections

After adding widgets, refresh Homepage. Widgets should display live data:

  • Plex: Shows recently added items and active streams
  • Radarr/Sonarr: Displays wanted items, queue status, and upcoming releases
  • Pi-hole: Shows queries blocked, percentage blocked, and total queries
  • Proxmox: Displays CPU usage, memory usage, and running VMs

If widgets don’t display data, check:

  1. API key is correct and not expired
  2. Service URL is accessible from Homepage container
  3. Widget type matches service type
  4. Check Homepage logs: docker logs homepage

Docker Autodiscovery and Automation

One of Homepage’s most powerful features is Docker autodiscovery. Instead of manually configuring services in services.yaml, Homepage can automatically detect services using Docker container labels.

Understanding Autodiscovery

Autodiscovery works by reading labels from your Docker containers. When you add specific labels to containers, Homepage automatically:

  1. Detects the container is running
  2. Reads the labels to get service information
  3. Adds the service to your dashboard
  4. Updates the dashboard when containers start/stop

This eliminates manual configuration and keeps your dashboard always in sync with your running services.

Docker Labels Syntax

Add labels to your containers using this format:

labels:
  homepage.group: GroupName
  homepage.name: ServiceName
  homepage.icon: icon.svg
  homepage.href: http://service-url
  homepage.description: Brief description
  homepage.widget.type: widgettype
  homepage.widget.url: http://service-url
  homepage.widget.key: api-key

Required Labels:

  • homepage.name: Service name (required for autodiscovery to work)

Recommended Labels:

  • homepage.group: Group name for organization
  • homepage.icon: Icon file name
  • homepage.href: URL to access service
  • homepage.description: Brief description

Implementing Autodiscovery

Here’s a complete Docker Compose example with Homepage labels:

version: '3.8'

services:
  # Jellyfin Media Server
  jellyfin:
    image: jellyfin/jellyfin:latest
    container_name: jellyfin
    ports:
      - 8096:8096
    volumes:
      - jellyfin-config:/config
      - jellyfin-media:/media
    labels:
      homepage.group: Media
      homepage.name: Jellyfin
      homepage.icon: jellyfin.svg
      homepage.href: http://localhost:8096
      homepage.description: Open Source Media Server
      homepage.widget.type: jellyfin
      homepage.widget.url: http://jellyfin:8096
      homepage.widget.key: YOUR_JELLYFIN_API_KEY
    restart: unless-stopped

  # Radarr Movie Management
  radarr:
    image: linuxserver/radarr:latest
    container_name: radarr
    ports:
      - 7878:7878
    environment:
      PUID: 1000
      PGID: 1000
      TZ: America/New_York
    volumes:
      - radarr-config:/config
      - media:/media
    labels:
      homepage.group: Downloads
      homepage.name: Radarr
      homepage.icon: radarr.svg
      homepage.href: http://localhost:7878
      homepage.description: Movie Management
      homepage.widget.type: radarr
      homepage.widget.url: http://radarr:7878
      homepage.widget.key: YOUR_RADARR_API_KEY
    restart: unless-stopped

  # Sonarr TV Management
  sonarr:
    image: linuxserver/sonarr:latest
    container_name: sonarr
    ports:
      - 8989:8989
    environment:
      PUID: 1000
      PGID: 1000
      TZ: America/New_York
    volumes:
      - sonarr-config:/config
      - media:/media
    labels:
      homepage.group: Downloads
      homepage.name: Sonarr
      homepage.icon: sonarr.svg
      homepage.href: http://localhost:8989
      homepage.description: TV Series Management
      homepage.widget.type: sonarr
      homepage.widget.url: http://sonarr:8989
      homepage.widget.key: YOUR_SONARR_API_KEY
    restart: unless-stopped

  # Pi-hole DNS
  pihole:
    image: pihole/pihole:latest
    container_name: pihole
    ports:
      - 53:53/tcp
      - 53:53/udp
      - 8080:80
    environment:
      TZ: America/New_York
      WEBPASSWORD: YOUR_ADMIN_PASSWORD
    volumes:
      - pihole-config:/etc/pihole
      - pihole-dnsmasq:/etc/dnsmasq.d
    labels:
      homepage.group: Network
      homepage.name: Pi-hole
      homepage.icon: pi-hole.svg
      homepage.href: http://localhost:8080/admin
      homepage.description: DNS Ad Blocking
      homepage.widget.type: pihole
      homepage.widget.url: http://pihole:80
      homepage.widget.key: YOUR_PIHOLE_API_KEY
    restart: unless-stopped

  # Homepage Dashboard
  homepage:
    image: ghcr.io/gethomepage/homepage:latest
    container_name: homepage
    ports:
      - 3000:3000
    volumes:
      - ./config:/app/config
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      HOMEPAGE_ALLOWED_HOSTS: localhost:3000
      PUID: 1000
      PGID: 1000
      TZ: America/New_York
    restart: unless-stopped

volumes:
  jellyfin-config:
  jellyfin-media:
  radarr-config:
  sonarr-config:
  pihole-config:
  pihole-dnsmasq:
  media:

Configuring Docker Socket Access

To enable autodiscovery, Homepage needs to communicate with Docker. Create config/docker.yaml:

# Simple Docker socket configuration
my-docker:
  socket: /var/run/docker.sock

With this configuration and the labels on your containers, Homepage will automatically discover and display all labeled services. No manual services.yaml entries needed!

Verifying Autodiscovery

After adding labels and restarting containers:

# Restart containers to apply labels
docker-compose restart

# Check container labels
docker inspect jellyfin | grep homepage

# Restart Homepage to detect changes
docker restart homepage

# View Homepage logs to verify detection
docker logs homepage

Visit your Homepage dashboard - you should see all labeled services appear automatically!

Customization and Theming

Homepage offers extensive customization options to make your dashboard uniquely yours.

Global Settings Configuration

Create or edit config/settings.yaml:

# Page Title and Branding
title: My Homelab Dashboard
subtitle: Central Hub
documentTitle: Homelab
logo: /icons/homelab-logo.png  # Optional custom logo

# Theme Configuration
theme: dark  # Options: dark, light
color: blue  # 24 colors available: slate, gray, zinc, neutral, stone, red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose, white

# Background and Appearance
background:
  image: https://images.unsplash.com/photo-1451187580459-43490279c0fa
  blur: sm  # xs, sm, md, lg, xl
  saturate: 50  # 0-100
  brightness: 70  # 0-100
  opacity: 20  # 0-100

headerStyle: boxed  # Options: boxed, underlined, clean
cardBlur: md  # Card background blur: xs, sm, md, lg, xl
radius: md  # Card corner radius: xs, sm, md, lg, xl

# Language and Locale
language: en
dateFormat: DD/MM/YYYY
timeFormat: HH:mm

# Layout Configuration
layout:
  Media:
    style: row
    columns: 3
  Downloads:
    style: row
    columns: 3
  Admin:
    style: row
    columns: 2
  Network:
    style: row
    columns: 4

# Header Items (top-right icons)
headerItems:
  - search
  - theme  # Dark/light mode toggle
  - help
  - keyboard

# Quicklaunch (Command Palette)
quicklaunch:
  enabled: true
  searchDescription: true
  hideVisitCount: false

# Search Provider Integration
searchQuery: /  # Shortcut to open search

# Widget Configuration
useEqualHeights: true  # Make all cards the same height

# Development and Debugging
logLevel: info  # Options: debug, info, warn, error

Available Theme Colors

Homepage supports 24 theme colors that change the accent color throughout the dashboard:

  • Neutrals: slate, gray, zinc, neutral, stone
  • Warm: red, orange, amber, yellow
  • Green Shades: lime, green, emerald, teal
  • Blues: cyan, sky, blue, indigo
  • Purples: violet, purple, fuchsia
  • Others: pink, rose, white

Try different colors to find your favorite aesthetic!

Custom CSS Styling

For advanced customization, create config/custom.css:

/* Custom Color Scheme */
:root {
  --primary-color: #3b82f6;
  --secondary-color: #1e40af;
  --accent-color: #0ea5e9;
}

/* Dark Mode Custom Colors */
@media (prefers-color-scheme: dark) {
  :root {
    --bg-primary: #0f172a;
    --bg-secondary: #1e293b;
    --text-primary: #f1f5f9;
    --text-secondary: #94a3b8;
  }
}

/* Service Card Hover Effects */
.service-card {
  transition: all 0.3s ease;
  border-radius: 12px;
}

.service-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 12px 24px rgba(0, 0, 0, 0.3);
}

/* Colored Left Border for Specific Services */
.service-card[title="Plex"] {
  border-left: 4px solid #e5a00d;
}

.service-card[title="Radarr"] {
  border-left: 4px solid #ffc230;
}

.service-card[title="Sonarr"] {
  border-left: 4px solid #35c5f4;
}

/* Custom Background Blur Effect */
body::before {
  content: '';
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  backdrop-filter: blur(10px);
  background: rgba(0, 0, 0, 0.4);
  z-index: -1;
}

/* Responsive Column Layout */
@media (max-width: 768px) {
  .service-grid {
    grid-template-columns: 1fr !important;
  }
}

/* Custom Font */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700&display=swap');

* {
  font-family: 'Inter', sans-serif;
}

/* Widget Customization */
.widget-label {
  font-weight: 600;
  color: var(--text-primary);
}

/* Hide Widgets on Mobile */
@media (max-width: 768px) {
  .widget-weather {
    display: none;
  }
}

Layout Customization Examples

Three-Column Asymmetric Layout

layout:
  LeftPanel:
    style: row
    columns: 1
  MainPanel:
    style: row
    columns: 2
  RightPanel:
    style: row
    columns: 1

Responsive Four-Column Layout

layout:
  Media:
    style: row
    columns: 4
  Downloads:
    style: row
    columns: 4
  Admin:
    style: row
    columns: 2

The layout automatically adjusts on mobile devices to a single column for better usability.

Bookmarks provide quick access to external websites and frequently visited pages.

Bookmark Configuration

Create or edit config/bookmarks.yaml:

# Development Tools
- Developer:
    - GitHub:
        icon: github.svg
        href: https://github.com/

    - GitLab:
        abbr: GL
        href: https://gitlab.com/

    - Stack Overflow:
        abbr: SO
        href: https://stackoverflow.com/

# Entertainment
- Entertainment:
    - YouTube:
        icon: youtube.svg
        href: https://youtube.com/

    - Netflix:
        icon: netflix.svg
        href: https://netflix.com/

    - Reddit:
        icon: reddit.svg
        href: https://reddit.com/

# Business & Productivity
- Productivity:
    - Gmail:
        icon: gmail.svg
        href: https://mail.google.com/
        target: newtab

    - Google Drive:
        icon: google-drive.svg
        href: https://drive.google.com/
        target: newtab

    - Notion:
        icon: notion.svg
        href: https://notion.so/

# Documentation & Learning
- Documentation:
    - Docker Docs:
        abbr: DK
        href: https://docs.docker.com/

    - Homepage Docs:
        abbr: HP
        href: https://gethomepage.dev/

    - MDN Web Docs:
        abbr: MDN
        href: https://developer.mozilla.org/

Bookmark Options:

  • icon: Use SVG or PNG icon (built-in icons or custom)
  • abbr: 2-3 letter abbreviation if no icon
  • href: URL to link to
  • target: Optional - newtab, email, or default (same window)

Icon Management

Homepage includes icons for hundreds of popular services. To use custom icons:

  1. Create config/icons/ directory
  2. Place your PNG or SVG icons there
  3. Reference them in configs: icon: /icons/my-custom-icon.svg

You can also use external icon URLs:

- Services:
    - Custom Service:
        icon: https://example.com/icon.svg
        href: https://example.com/

Advanced Features and Security

Reverse Proxy Configuration

For security, always run Homepage behind a reverse proxy with SSL and authentication. Homepage does not include built-in authentication.

Nginx Configuration

Create /etc/nginx/sites-available/homepage:

server {
    listen 443 ssl http2;
    server_name dashboard.example.com;

    # SSL Configuration
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # SSL Security Settings
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    # Basic Authentication
    auth_basic "Homelab Access";
    auth_basic_user_file /etc/nginx/.htpasswd;

    # Proxy Configuration
    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_buffering off;
    }
}

# HTTP to HTTPS redirect
server {
    listen 80;
    server_name dashboard.example.com;
    return 301 https://$server_name$request_uri;
}

Create basic authentication credentials:

# Install htpasswd utility
sudo apt install apache2-utils

# Create password file
sudo htpasswd -c /etc/nginx/.htpasswd admin

# Enable site
sudo ln -s /etc/nginx/sites-available/homepage /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Traefik Configuration

Add Traefik labels to your Homepage service:

homepage:
  image: ghcr.io/gethomepage/homepage:latest
  container_name: homepage
  ports:
    - 3000:3000
  volumes:
    - ./config:/app/config
    - /var/run/docker.sock:/var/run/docker.sock:ro
  environment:
    HOMEPAGE_ALLOWED_HOSTS: dashboard.example.com
  labels:
    # Traefik Configuration
    - "traefik.enable=true"
    - "traefik.http.routers.homepage.rule=Host(`dashboard.example.com`)"
    - "traefik.http.routers.homepage.entrypoints=websecure"
    - "traefik.http.routers.homepage.tls.certresolver=letsencrypt"
    - "traefik.http.services.homepage.loadbalancer.server.port=3000"

    # Basic Authentication Middleware
    - "traefik.http.routers.homepage.middlewares=homepage-auth"
    - "traefik.http.middlewares.homepage-auth.basicauth.users=admin:$$apr1$$hash$$here"
  restart: unless-stopped

Docker Socket Security

Exposing the Docker socket directly poses a security risk. Use a Docker socket proxy to limit permissions:

version: '3.8'

services:
  # Docker Socket Proxy
  docker-proxy:
    image: tecnativa/docker-socket-proxy
    container_name: docker-socket-proxy
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      CONTAINERS: 1  # Allow reading container info
      SERVICES: 1    # Allow reading service info
      TASKS: 1       # Allow reading task info
      POST: 0        # Disable write operations
    ports:
      - 127.0.0.1:2375:2375
    restart: unless-stopped

  # Homepage using Docker Proxy
  homepage:
    image: ghcr.io/gethomepage/homepage:latest
    container_name: homepage
    depends_on:
      - docker-proxy
    ports:
      - 3000:3000
    volumes:
      - ./config:/app/config
    environment:
      HOMEPAGE_ALLOWED_HOSTS: dashboard.example.com
      DOCKER_HOST: tcp://docker-proxy:2375
      PUID: 1000
      PGID: 1000
    restart: unless-stopped

Then configure config/docker.yaml:

my-docker:
  host: tcp://docker-proxy:2375

This setup limits Homepage’s access to read-only Docker operations, significantly improving security.

AI Automation and Intelligence

While Homepage doesn’t include built-in AI features, you can integrate it with various AI tools and automation platforms to create an intelligent dashboard experience.

n8n Workflow Automation

n8n is an open-source workflow automation tool perfect for Homepage integration.

Service Health Monitoring Workflow

Create an n8n workflow that monitors your services and sends alerts:

# n8n Workflow: Service Health Monitor
# Deploy alongside Homepage

services:
  n8n:
    image: n8nio/n8n:latest
    container_name: n8n
    ports:
      - 5678:5678
    environment:
      - N8N_BASIC_AUTH_ACTIVE=true
      - N8N_BASIC_AUTH_USER=admin
      - N8N_BASIC_AUTH_PASSWORD=your-password
      - WEBHOOK_URL=https://n8n.example.com/
    volumes:
      - n8n-data:/home/node/.n8n
    restart: unless-stopped

volumes:
  n8n-data:

Workflow Logic:

  1. Trigger: Run every 5 minutes
  2. HTTP Request: Check service health endpoints
  3. IF Node: Service is down?
  4. Get Service Info: Query Homepage config
  5. Generate Alert: Create notification message
  6. Send Notification: Discord, Email, Slack, or Telegram
  7. Update Status: Log incident to database

Example n8n Workflow (pseudo-code):

Trigger: Schedule (Every 5 minutes)
  ├─> HTTP Request: GET http://jellyfin:8096/health
  ├─> IF: Status Code != 200
  │   ├─> Read File: /app/config/services.yaml
  │   ├─> Extract: Service name and details
  │   ├─> Compose Message: "Jellyfin is down! Last check: [timestamp]"
  │   ├─> Discord Webhook: Send alert
  │   └─> Database: Log downtime event
  └─> Success: Service is healthy

Automated Daily Reports

Generate daily summary reports of your homelab:

Trigger: Schedule (Daily at 9 AM)
  ├─> HTTP Request: Radarr API - Get movie statistics
  ├─> HTTP Request: Sonarr API - Get TV statistics
  ├─> HTTP Request: Plex API - Get watch history
  ├─> HTTP Request: Proxmox API - Get resource usage
  ├─> Ollama LLM: Generate human-readable summary
  ├─> Format: Create beautiful HTML report
  └─> Send Email: Daily homelab digest

Automatic Service Discovery

Automatically update Homepage when new containers are created:

Trigger: Webhook from Docker events
  ├─> Parse: Docker event JSON
  ├─> IF: Container has homepage.* labels
  │   ├─> Extract: All homepage labels
  │   ├─> Read: Current services.yaml
  │   ├─> Generate: New service entry
  │   ├─> Write: Updated services.yaml
  │   ├─> API Call: Restart Homepage container
  │   └─> Notify: Admin via Discord
  └─> Log: Event processed

Ollama Local LLM Integration

Ollama provides local large language models that can power intelligent features without sending data to external services.

Deploy Ollama

services:
  ollama:
    image: ollama/ollama:latest
    container_name: ollama
    ports:
      - 11434:11434
    volumes:
      - ollama-data:/root/.ollama
    restart: unless-stopped

volumes:
  ollama-data:

Pull a model:

docker exec -it ollama ollama pull llama2

Implement AI-powered search that understands natural language:

User speaks: "Show me my media servers"
  ├─> Capture: Voice or text input
  ├─> Send to Ollama: Process query
  ├─> LLM Response: Extract keywords ["media", "servers"]
  ├─> Query: services.yaml for matches
  ├─> Filter: Return Plex, Jellyfin, Emby
  └─> Display: Highlight matching services

n8n Workflow Implementation:

Webhook: Receive search query
  ├─> Ollama LLM: Analyze query intent
  │   Prompt: "Extract keywords from: 'Show me my media servers'"
  │   Response: ["media", "server", "streaming"]
  ├─> Read: services.yaml
  ├─> Match: Find services with matching keywords
  ├─> Return: JSON array of matching services
  └─> Homepage: Highlight results

Intelligent Service Recommendations

Analyze usage patterns and suggest optimizations:

Trigger: Weekly on Sunday
  ├─> Collect: Service access logs
  ├─> Analyze: Usage frequency and patterns
  ├─> Ollama LLM: Generate insights
  │   Prompt: "Analyze this service usage data and suggest improvements"
  │   Data: {services: [...], access_counts: [...], last_accessed: [...]}
  ├─> Generate: Recommendations
  │   • "You haven't accessed Lidarr in 30 days. Consider removing it."
  │   • "Plex is accessed 50x/day. Move it to top of dashboard."
  │   • "Radarr and Sonarr are always used together. Group them."
  └─> Email: Weekly optimization report

Log Analysis and Anomaly Detection

Automatically analyze service logs for issues:

Trigger: Hourly
  ├─> Collect Logs: From all services via Docker API
  ├─> Send to Ollama: Analyze logs
  │   Prompt: "Analyze these logs for errors or anomalies"
  ├─> LLM Response: Detected issues with explanations
  ├─> IF: Critical issues found
  │   ├─> Generate: Human-readable alert
  │   ├─> Create: Homepage notification widget
  │   └─> Send: Alert via Discord/Email
  └─> Store: Analysis results for trending

OpenWebUI Integration

OpenWebUI provides a ChatGPT-like interface for interacting with your homelab.

Deploy OpenWebUI

services:
  open-webui:
    image: ghcr.io/open-webui/open-webui:main
    container_name: open-webui
    ports:
      - 8080:8080
    environment:
      - OLLAMA_BASE_URL=http://ollama:11434
    volumes:
      - open-webui-data:/app/backend/data
    depends_on:
      - ollama
    restart: unless-stopped

volumes:
  open-webui-data:

Chatbot Commands for Homepage

Create custom functions in OpenWebUI that interact with your homelab:

Example Queries:

  1. “Which services use the most resources?”

    • Query Proxmox/Docker stats
    • Generate resource usage report
    • Display top consumers
  2. “What’s new on Plex?”

    • Query Plex API for recently added media
    • Format as readable list
    • Provide direct links
  3. “Are all services healthy?”

    • Check health endpoints of all services
    • Report status of each
    • Alert on any failures
  4. “Show me Radarr’s download queue”

    • Query Radarr API
    • Format queue information
    • Estimate completion times

Predictive Maintenance

Use AI to predict issues before they occur:

OpenWebUI Query: "Will I run out of storage soon?"
  ├─> Gather: Historical disk usage data
  ├─> Ollama Analysis: Trend prediction
  │   Prompt: "Based on this disk usage data, predict when storage will be full"
  │   Data: [{date: "2024-01-01", used: 500GB}, {date: "2024-01-08", used: 550GB}, ...]
  ├─> LLM Response: "Based on current trends, storage will be full in approximately 45 days"
  ├─> Generate: Recommendations for cleanup
  └─> Display: Warning on Homepage dashboard

PrivateGPT for Documentation

PrivateGPT enables AI-powered search of your documentation without sending data externally.

Service Documentation Assistant

Create a knowledge base of all your service configurations:

services:
  privategpt:
    image: zylon/private-gpt:latest
    container_name: privategpt
    ports:
      - 8001:8001
    volumes:
      - privategpt-data:/app/data
      - ./docs:/docs  # Mount documentation directory
    environment:
      - MODEL=llama2
      - EMBEDDINGS_MODEL=all-MiniLM-L6-v2
    restart: unless-stopped

volumes:
  privategpt-data:

Usage Examples:

  • “How do I configure Radarr quality profiles?”

    • PrivateGPT searches your embedded documentation
    • Provides step-by-step instructions
    • Links to relevant services on Homepage
  • “What are my Jellyfin user permissions?”

    • Searches configuration files
    • Explains current setup
    • Suggests security improvements

Configuration Validation

Automatically check your configs for best practices:

Background Task: Daily
  ├─> Read: All YAML configuration files
  ├─> PrivateGPT Analysis: Check for issues
  │   Prompt: "Review these configurations for security and best practices"
  ├─> Generate: Report of findings
  │   • "API key exposed in services.yaml - use environment variables"
  │   • "Docker socket mounted with write access - use socket proxy"
  │   • "No rate limiting on Radarr widget - may cause API throttling"
  └─> Display: Recommendations on Homepage

Practical AI-Powered Features

1. Smart Service Grouping

# n8n Workflow: Analyze and Re-organize Services
services:
  smart-grouping:
    steps:
      - analyze-usage: Track which services are accessed together
      - ollama-suggest: "These services are often used together: [Radarr, Sonarr, Jellyfin]"
      - auto-group: Create "Media Stack" group
      - update-config: Apply new grouping to services.yaml
      - notify-user: "Dashboard reorganized for better efficiency"

Enable natural language search across your dashboard:

// Example search queries processed by AI
"Show download services" → [Radarr, Sonarr, Transmission, qBittorrent]
"What's using CPU?" → Query Proxmox/Glances, display top consumers
"Is media ready?" → Check Plex status, show recently added content
"Which services are down?" → Health check all services, report failures

3. Predictive Maintenance Alerts

Monitor trends and predict issues:

AI Monitoring Tasks:
  ├─> Storage: "75% full, will reach capacity in 2 weeks"
  ├─> Services: "Radarr error rate increased 300% in past 24h"
  ├─> Containers: "Jellyfin has restarted 5 times - investigate logs"
  ├─> Network: "Bandwidth usage spike detected - possible issue"
  └─> Display: Prominent alerts on Homepage dashboard

4. Voice Control Integration

Use voice commands to control your homelab:

# Voice Command Workflow
voice-command:
  trigger: Webhook from voice assistant
  steps:
    - transcribe: Convert speech to text
    - ollama-parse: Understand intent
    - execute: Perform action
    - respond: Confirm completion

# Examples:
"Open Plex" → Redirect to Plex URL
"Check server status" → Display Proxmox stats
"What's downloading?" → Show Radarr/Sonarr queues

Complete AI-Enhanced Homepage Stack

Here’s a complete Docker Compose file for an AI-powered Homepage setup:

version: '3.8'

services:
  # Homepage Dashboard
  homepage:
    image: ghcr.io/gethomepage/homepage:latest
    container_name: homepage
    ports:
      - 3000:3000
    volumes:
      - ./config:/app/config
    environment:
      HOMEPAGE_ALLOWED_HOSTS: dashboard.example.com
      DOCKER_HOST: tcp://docker-proxy:2375
      PUID: 1000
      PGID: 1000
    depends_on:
      - docker-proxy
    restart: unless-stopped

  # Docker Socket Proxy (Security)
  docker-proxy:
    image: tecnativa/docker-socket-proxy
    container_name: docker-socket-proxy
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      CONTAINERS: 1
      SERVICES: 1
      TASKS: 1
      POST: 0
    restart: unless-stopped

  # n8n Workflow Automation
  n8n:
    image: n8nio/n8n:latest
    container_name: n8n
    ports:
      - 5678:5678
    environment:
      - N8N_BASIC_AUTH_ACTIVE=true
      - N8N_BASIC_AUTH_USER=admin
      - N8N_BASIC_AUTH_PASSWORD=secure_password
      - WEBHOOK_URL=https://n8n.example.com/
    volumes:
      - n8n-data:/home/node/.n8n
    restart: unless-stopped

  # Ollama Local LLM
  ollama:
    image: ollama/ollama:latest
    container_name: ollama
    ports:
      - 11434:11434
    volumes:
      - ollama-data:/root/.ollama
    restart: unless-stopped

  # OpenWebUI Chat Interface
  open-webui:
    image: ghcr.io/open-webui/open-webui:main
    container_name: open-webui
    ports:
      - 8080:8080
    environment:
      - OLLAMA_BASE_URL=http://ollama:11434
    volumes:
      - open-webui-data:/app/backend/data
    depends_on:
      - ollama
    restart: unless-stopped

  # PrivateGPT Documentation Assistant
  privategpt:
    image: zylon/private-gpt:latest
    container_name: privategpt
    ports:
      - 8001:8001
    volumes:
      - privategpt-data:/app/data
      - ./docs:/docs
    environment:
      - MODEL=llama2
    restart: unless-stopped

volumes:
  n8n-data:
  ollama-data:
  open-webui-data:
  privategpt-data:

Troubleshooting and Common Issues

Services Not Appearing

Problem: Labeled containers don’t show up on Homepage dashboard.

Solutions:

  1. Verify label syntax: Check for typos in label names

    docker inspect container-name | grep homepage
  2. Ensure homepage.name exists: This is the only required label

    labels:
      homepage.name: ServiceName  # Required!
  3. Check Homepage logs:

    docker logs homepage
  4. Verify Docker socket access:

    ls -la /var/run/docker.sock
    docker exec homepage ls -la /var/run/docker.sock
  5. Restart Homepage:

    docker restart homepage

Widgets Not Displaying Data

Problem: Service widgets show no data or loading indefinitely.

Solutions:

  1. Verify API key: Check the key is correct and not expired

    • Most services show API keys in Settings → General
  2. Test service URL: Ensure Homepage can reach the service

    docker exec homepage curl http://radarr:7878/api/v3/system/status?apikey=YOUR_KEY
  3. Check widget type: Must match service type exactly

    widget:
      type: radarr  # Must match exactly - not "Radarr" or "radar"
  4. Review Homepage logs:

    docker logs homepage 2>&1 | grep -i error
  5. Verify network connectivity: Ensure containers are on same network

    docker network inspect bridge

Configuration File Errors

Problem: Homepage shows blank page or YAML errors.

Solutions:

  1. Validate YAML syntax: Use a YAML validator

    # Install yamllint
    pip install yamllint
    
    # Validate files
    yamllint config/services.yaml
    yamllint config/settings.yaml
  2. Check indentation: Use spaces, not tabs (2 or 4 spaces consistently)

    # Correct
    - Media:
        - Plex:
            icon: plex.svg
    
    # Wrong (inconsistent indentation)
    - Media:
       - Plex:
             icon: plex.svg
  3. Common mistakes:

    • Missing colons after keys
    • Quotes around special characters
    • List items must start with -
  4. View Homepage error logs:

    docker logs homepage --tail 50

Performance Issues

Problem: Homepage loads slowly or uses excessive resources.

Solutions:

  1. Reduce widget refresh intervals: Edit services with frequent updates

    widget:
      type: radarr
      url: http://radarr:7878
      key: api-key
      refreshInterval: 300000  # 5 minutes instead of default
  2. Limit number of widgets: Too many API calls can slow performance

    • Remove widgets from less important services
    • Use groups to organize better
  3. Check container resources:

    docker stats homepage
  4. Clear browser cache: Old cached data can cause issues

    • Chrome: Ctrl+Shift+Del
    • Firefox: Ctrl+Shift+Del
  5. Optimize images: Large background images impact load time

    • Use compressed images
    • Consider removing background: background: null

Docker Socket Permission Issues

Problem: Permission denied accessing Docker socket.

Solutions:

  1. Fix socket permissions:

    sudo chmod 666 /var/run/docker.sock
    # OR add user to docker group (preferred)
    sudo usermod -aG docker $USER
    newgrp docker
  2. Use docker-socket-proxy (recommended for security):

    docker-proxy:
      image: tecnativa/docker-socket-proxy
      volumes:
        - /var/run/docker.sock:/var/run/docker.sock:ro
      environment:
        CONTAINERS: 1
  3. Verify mount in docker-compose:

    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro

Debugging Tools and Techniques

Browser Developer Console (F12):

  • Check for JavaScript errors
  • View network requests to services
  • Inspect failed API calls

Docker Logs:

# View all logs
docker logs homepage

# Follow logs in real-time
docker logs -f homepage

# View last 100 lines
docker logs --tail 100 homepage

# Search for errors
docker logs homepage 2>&1 | grep -i error

Container Network Testing:

# Test connectivity from Homepage to service
docker exec homepage ping radarr
docker exec homepage curl http://radarr:7878

# Check if port is accessible
docker exec homepage nc -zv radarr 7878

API Key Validation:

# Test Radarr API
curl -H "X-Api-Key: YOUR_API_KEY" http://localhost:7878/api/v3/system/status

# Test Sonarr API
curl -H "X-Api-Key: YOUR_API_KEY" http://localhost:8989/api/v3/system/status

Extending Homepage

Once you have Homepage running, consider these enhancements:

  1. Custom Widgets: Create widgets for unsupported services
  2. Webhook Integration: Trigger actions from Homepage clicks
  3. API Integration: Build custom service integrations
  4. Mobile App: Create a native app using Tauri or React Native
  5. Contributing: Submit service integrations to Homepage project

Monitoring Stack:

  • Prometheus + Grafana for metrics visualization
  • Glances for system monitoring
  • Uptime Kuma for service availability monitoring

Automation:

  • n8n for workflow automation
  • Home Assistant for smart home integration
  • Cron jobs for scheduled maintenance

AI and Intelligence:

  • Ollama for local LLMs
  • OpenWebUI for chat interface
  • PrivateGPT for document search
  • Whisper for voice commands

Backup and Disaster Recovery:

  • Include Homepage config in your backup strategy
  • Version control configs with Git
  • Test restoration procedures regularly

Scaling Homepage

For larger deployments or organizations:

  1. Kubernetes Deployment: Use Helm charts for scalability
  2. Multiple Instances: Deploy for redundancy
  3. Load Balancing: Distribute traffic across instances
  4. Configuration Management: Use GitOps for config sync
  5. High Availability: Deploy across multiple nodes

Community and Support

Continue your homelab journey with these related topics:

  • Reverse Proxy Setup: Nginx, Traefik, or Caddy configuration
  • Docker Fundamentals: Deep dive into containerization
  • Kubernetes for Homelabs: Container orchestration
  • Home Assistant: Smart home automation
  • Monitoring with Prometheus: Comprehensive metrics collection
  • n8n Automation: Workflow automation platform
  • Local AI with Ollama: Self-hosted language models

Summary

You’ve now learned how to:

  • Install and configure Homepage with Docker Compose
  • Create service groups and add service widgets
  • Implement Docker autodiscovery with container labels
  • Customize appearance with themes and custom CSS
  • Organize bookmarks for quick access
  • Secure Homepage behind a reverse proxy
  • Integrate AI tools for intelligent automation
  • Troubleshoot common configuration issues

Homepage provides a powerful, flexible foundation for managing your homelab services. With Docker autodiscovery, extensive service integrations, and AI automation capabilities, it can grow and adapt as your homelab expands.

The combination of Homepage’s dashboard capabilities with AI tools like Ollama and n8n creates an intelligent homelab management system that goes beyond simple service access - it can predict issues, automate responses, and provide insights into your infrastructure.

Start with the basics, add services gradually, and explore AI integrations once you’re comfortable with the core functionality. Your perfect homelab dashboard is just a few YAML files away!

Additional Resources

Official Documentation

Community Resources

  • Homepage GitHub: https://github.com/gethomepage/homepage
  • Techno Tim Tutorial: Meet Homepage video guide
  • Road to Homelab: Complete Homepage setup guide
  • r/homelab: Reddit community with example configs

AI and Automation


Last Updated: 2025-12-16 Guide Version: 1.0 Tested with Homepage: Latest (December 2025)