Files
Homepage/README.md

11 KiB
Raw Blame History

Services Homepage

A lightweight, self-hosted dashboard for quick access to your Docker services with a modern holographic UI design.

License Docker

Features

  • 🎨 Holographic Glass Design - Modern liquid glass buttons with animated shimmer effects
  • 🎯 Dynamic Service Loading - Services configured via simple XML file
  • 🔍 Smart URL Resolution - Automatic handling of ports, protocols, and hostnames
  • 🎭 Icon Integration - Includes Simple Icons pack (3000+ brand logos)
  • 📱 Responsive Layout - Works seamlessly on desktop and mobile
  • 🐳 Docker-Ready - Single-container deployment with nginx
  • Lightweight - Minimal resources, fast loading
  • 🔎 Search & Filter - Instant search with keyboard shortcut (press /)
  • Connection Details - Info button shows hostname/port for each service
  • 🎮 Keyboard Navigation - Arrow keys to navigate, Enter to open, Esc to clear
  • 🟢 Status Indicators - Optional visual status (online/offline/maintenance)
  • 🏥 Automatic Health Checks - Real-time ping tests to detect service availability

Quick Start

1. Deploy with Docker Compose

docker-compose up -d

The homepage will be available at http://localhost:8088

2. Configure Your Services

Edit services.xml to add your services:

<?xml version="1.0" encoding="UTF-8"?>
<services>
  <service 
    name="Portainer" 
    proto="https" 
    host="portainer.example.com" 
    logo="portainer.svg" 
  />
  <service 
    name="Jellyfin" 
    proto="http" 
    port="8096" 
    logo="jellyfin.svg" 
  />
</services>

3. Restart to Apply Changes

docker-compose restart

Configuration Guide

Service Attributes

Attribute Required Description Example
name Yes Display name for the service "Nextcloud"
proto No Protocol (http/https) "https" (default: "http")
port No Port number "8080"
host No Custom hostname or full URL "nextcloud.example.com"
logo No Icon filename in /logos/ "nextcloud.svg"
status No Set to "maintenance" to skip health check "maintenance"
check-health No Enable/disable auto health check "true" (default) or "false"

URL Resolution Logic

The service URL is built using this priority:

  1. Full URL - If host starts with http:// or https://, use as-is
  2. Hostname with Port - If host contains :port, use proto://host:port
  3. Hostname Only - If host is set (no port), use https://host (ignores proto and port)
  4. Fallback - Use current page hostname with specified proto and port

Examples

<!-- Full URL (ignores proto and port) -->
<service name="Example" host="https://example.com/app" />

<!-- Public domain (defaults to HTTPS) -->
<service name="Nextcloud" host="cloud.example.com" logo="nextcloud.svg" />

<!-- Custom port on domain -->
<service name="Jellyfin" host="media.example.com:8096" proto="http" logo="jellyfin.svg" />

<!-- Local service (uses page hostname) -->
<service name="Portainer" proto="https" port="9443" logo="portainer.svg" />

<!-- Service with status indicator -->
<service name="Home Assistant" proto="http" port="8123" logo="homeassistant.svg" status="online" />

Keyboard Shortcuts

  • / - Focus the search bar (press from anywhere)
  • Arrow Keys - Navigate between service cards (Up/Down/Left/Right)
  • Enter - Open the selected service in a new tab
  • Esc - Clear the current selection

Info Button

When a service has both a hostname and port configured, a small info button (ⓘ) appears in the bottom-right corner of the card. Click it to view connection details including:

  • Service name
  • Hostname
  • Port number
  • Protocol

Status Indicators

Services are automatically checked for availability when the page loads. Status indicators appear in the top-right corner of each card:

<!-- Automatic health check (default behavior) -->
<service name="Jellyfin" proto="http" port="8096" logo="jellyfin.svg" />

<!-- Manual maintenance mode (skips health check) -->
<service name="Nextcloud" status="maintenance" host="cloud.example.com" logo="nextcloud.svg" />

<!-- Disable health check for a service -->
<service name="Legacy App" check-health="false" proto="http" port="8080" logo="app.svg" />

Status colors:

  • Gray spinning (checking) - Currently testing service availability
  • Green pulsing (online) - Service responded successfully to health check
  • Red (offline) - Service failed to respond or timed out (5 seconds)
  • Orange (maintenance) - Manual maintenance mode, health check skipped

How Health Checks Work

  • Each service is automatically pinged when the page loads
  • Uses a 5-second timeout per service
  • Checks run in parallel for all services
  • Services marked status="maintenance" skip the health check
  • Set check-health="false" to disable checking for specific services
  • No server-side component needed - runs entirely in the browser

Icon Management

Using Included Icons

The repository includes Simple Icons (3000+ brand logos). Available icons are in:

logos/simple-icons/icons/

Adding Custom Icons

  1. Add your SVG file to the logos/ directory
  2. Reference it in services.xml:
<service name="MyApp" logo="myapp.svg" />

Icon Styling

All icons are automatically styled white using CSS filters. To customize:

Edit styles.css and modify the .card .logo rule:

.card .logo {
  filter: brightness(0) invert(1);  /* White icons */
  /* OR */
  filter: hue-rotate(180deg);       /* Color shift */
}

Customization

Theme Colors

Edit CSS variables in styles.css:

:root {
  --bg: #0f1720;           /* Background color */
  --card: #0b1220;         /* Card background */
  --accent: #4f46e5;       /* Accent color (purple) */
  --muted: #94a3b8;        /* Muted text */
}

Holographic Effects

The holographic button effects include:

  • Shimmer Animation - Continuous light sweep (8s loop, 3s on hover)
  • Gradient Background - Purple/pink gradient blend
  • Glowing Border - Animated gradient border on hover
  • Backdrop Blur - Glass-like frosted effect

To adjust shimmer speed, modify the @keyframes shimmer animation:

.card::before {
  animation: shimmer 8s infinite linear;  /* Change 8s to adjust speed */
}

Layout

Change grid responsiveness in styles.css:

.grid {
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  /* Adjust minmax() to change card width */
}

File Structure

services-homepage/
├── docker-compose.yml      # Docker deployment config
├── Dockerfile             # Custom nginx build (if needed)
├── index.html             # Main HTML page
├── styles.css             # Holographic UI styles
├── services.xml           # Service definitions
├── README.md              # This file
├── LICENSE                # License information
└── logos/                 # Icon directory
    ├── simple-icons/      # Simple Icons pack (3000+ logos)
    ├── default.svg        # Fallback icon
    ├── gitea.svg
    ├── jellyfin.svg
    ├── nextcloud.svg
    └── ...

Updating Icons

Replace All Icons with Simple Icons

cd logos
for f in *.svg; do
  basename=$(basename "$f" .svg)
  match=$(find simple-icons/icons -type f -iname "*${basename}*.svg" -print -quit)
  [ -n "$match" ] && cp "$match" "$f" && echo "Updated: $f"
done

Find Available Icons

ls logos/simple-icons/icons/ | grep -i "keyword"

Backup and Recovery

Icon backups are automatically created in:

logos/backup-YYYYMMDD-HHMMSS/

To restore from backup:

cp logos/backup-20251123-231406/*.svg logos/
docker-compose restart

Troubleshooting

Services Not Loading

  1. Check services.xml syntax:
xmllint --noout services.xml
  1. Check browser console for errors (F12)

  2. Verify file permissions:

chmod 644 services.xml index.html styles.css
chmod 755 logos/

Icons Not Displaying

  1. Verify icon exists:
ls -lh logos/youricon.svg
  1. Check icon reference in services.xml matches filename exactly

  2. Clear browser cache (Ctrl+Shift+R)

Container Issues

# View logs
docker logs services-homepage

# Restart container
docker-compose restart

# Rebuild if files changed
docker-compose up -d --force-recreate

Performance

  • Image Size: ~45MB (nginx:alpine base)
  • Memory Usage: ~5-10MB
  • Load Time: <100ms (local network)
  • Icons: Cached by browser after first load

Browser Support

  • Chrome/Edge 90+
  • Firefox 88+
  • Safari 14+
  • Mobile browsers (iOS Safari, Chrome Android)

Security

  • All volumes mounted read-only (:ro)
  • No external dependencies at runtime
  • Logs automatically rotated (5MB max, 2 files)
  • CORS not enabled (same-origin only)

Advanced Usage

Custom Nginx Config

Create nginx.conf and mount it:

volumes:
  - ./nginx.conf:/etc/nginx/nginx.conf:ro

Adding Authentication

Use a reverse proxy (Nginx Proxy Manager, Caddy, Traefik) with basic auth:

location / {
  auth_basic "Services";
  auth_basic_user_file /etc/nginx/.htpasswd;
  proxy_pass http://services-homepage:80;
}

Dynamic Port Updates

For services with dynamic ports (e.g., Transmission behind VPN), use environment variables:

<service name="Transmission" proto="http" port="${TRANS_PORT}" logo="transmission.svg" />

Then update via script or use a template processor.

Contributing

Contributions welcome! Completed features:

  • Search/filter functionality with keyboard shortcut
  • Keyboard navigation (arrow keys, Enter, Esc)
  • Service status indicators (online/offline/maintenance)
  • Info button showing connection details

Areas for future improvement:

  • Service health checks (automatic ping/availability detection)
  • Drag-and-drop reordering
  • Categorized sections/groups
  • Custom themes/color schemes
  • Export/import service configurations

License

MIT License - See LICENSE file for details

Credits

  • Icons: Simple Icons (CC0 1.0 Universal)
  • Design Inspiration: Holographic UI by vishnu137 on CodePen
  • Web Server: nginx Alpine

Support

For issues, questions, or suggestions:

  1. Check this README first
  2. Review browser console for errors
  3. Check Docker logs: docker logs services-homepage
  4. Verify services.xml syntax

Version: 1.0.0
Last Updated: November 23, 2025