My Homepage Dashboard
My Homepage Dashboard: The Ultimate Homelab Control Center
Introduction
The modern homelab has evolved into a complex ecosystem of self-hosted services - from media servers and file shares to CI/CD pipelines and monitoring stacks. As your infrastructure grows, so does the operational overhead of managing disparate web interfaces, container states, and authentication flows. This is where a centralized homepage dashboard becomes mission-critical infrastructure.
For DevOps engineers and sysadmins running self-hosted environments, the challenge isn’t just deploying services - it’s maintaining situational awareness across your entire stack. The Reddit user’s experience highlights this pain point vividly: needing immediate container controls without switching contexts to Portainer, and seamless authentication management through Authentik integration.
In this comprehensive guide, you’ll learn how to implement a production-grade dashboard solution using gethomepage, extending its capabilities with professional-grade enhancements:
- Direct Docker container management via Portainer API integration
- SSO session control through Authentik workflows
- Enterprise-ready security hardening
- Performance-optimized configuration
- Troubleshooting methodologies for edge cases
We’ll focus on implementations that meet enterprise DevOps standards while remaining accessible for homelab enthusiasts. Whether you’re managing 5 containers or 50 microservices, these techniques will transform your dashboard from a simple bookmark page to an operational command center.
Understanding Homepage Dashboards
What is gethomepage?
gethomepage (https://gethomepage.dev/) is an open-source application dashboard designed specifically for self-hosted environments. Unlike generic bookmark managers, it provides dynamic integration with your infrastructure through:
- Service discovery for Docker containers and Kubernetes pods
- Health monitoring with status indicators
- API-driven controls for container management
- Custom widget system for extensibility
Evolution of Dashboard Solutions
The self-hosted dashboard space has evolved through three generations:
| Generation | Examples | Limitations |
|---|---|---|
| 1st | HTPC Manager, Muximux | Static links only |
| 2nd | Heimdall, Organizr | Basic service discovery |
| 3rd | gethomepage, Homarr | API integrations, live controls |
gethomepage represents the current state-of-the-art with its Go-based architecture providing lower resource consumption (<50MB RAM) compared to PHP-based alternatives, while offering true bidirectional integration with infrastructure components.
Key Technical Differentiators
- Docker Socket API Integration
- Real-time container status updates
- Direct control surface without Portainer GUI
- Label-based service categorization
- Extensible Authentication
- OAuth2/OIDC support (Authentik, Authelia)
- Fine-grained access controls
- Session management hooks
- Declarative Configuration
1 2 3 4 5 6 7 8
# homepage.yaml example services: - name: "Service Status" icon: "heart-pulse" widget: type: "docker" url: "http://docker-socket-proxy:3000" group: "prod"
When to Choose gethomepage
Optimal use cases:
- Mixed Docker/VM environments
- Teams requiring granular access controls
- Environments with >10 services
- Security-conscious deployments
Alternatives to consider:
- Heimdall: Simpler deployments <5 services
- Homarr: Better Kubernetes integration
- Organizr: PHP-based with plugin ecosystem
Prerequisites
Hardware Requirements
| Component | Minimum | Recommended |
|---|---|---|
| CPU | x64 1 core | x64 2 cores |
| RAM | 512MB | 2GB |
| Storage | 100MB | 1GB SSD |
Software Dependencies
- Docker Engine v20.10.14+ with API access:
1 2
docker version --format '' # Output: 20.10.23
Reverse Proxy (Traefik, Caddy, or Nginx) with HTTPS termination
Portainer v2.18+ (for container controls)
- Authentik v2023.5+ (for SSO integration)
Security Preconfiguration
- Create dedicated Docker network:
1
docker network create --driver=bridge --subnet=172.28.0.0/16 dashboard_net
- Set up Docker Socket Proxy: ```yaml
docker-compose.socket-proxy.yml
services: docker-socket-proxy: image: tecnativa/docker-socket-proxy networks:
- dashboard_net volumes:
- /var/run/docker.sock:/var/run/docker.sock environment:
- SERVICES=1
- SWARM=1
- TASKS=1 ```
- Generate API credentials:
- Portainer API key
- Authentik service account token
Installation & Configuration
Step 1: Core Deployment
1
mkdir -p /opt/homepage && cd /opt/homepage
Create docker-compose.yml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
version: '3.8'
services:
homepage:
image: ghcr.io/benphelps/homepage:latest
container_name: homepage
networks:
- dashboard_net
volumes:
- ./config:/app/config
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- PUID=1000
- PGID=1000
restart: unless-stopped
networks:
dashboard_net:
external: true
Step 2: Portainer API Integration
- Create Portainer API key:
1 2
curl -X POST "https://portainer.yourdomain.com/api/endpoints/2/docker/containers/json" \ -H "X-API-Key: your_portainer_api_key"
- Configure
services.yaml:1 2 3 4 5 6 7 8 9
- name: Portainer icon: portainer.png widget: type: docker url: http://docker-socket-proxy:3000 usePortainer: true portainer: url: https://portainer.yourdomain.com key: your_portainer_api_key
Step 3: Authentik SSO Integration
- Create OAuth2 provider in Authentik:
- Redirect URI:
https://homepage.yourdomain.com/oauth2/callback - Signing Key:
authentik Self-signed Certificate
- Redirect URI:
- Configure
homepage.yaml:1 2 3 4 5 6 7 8
auth: provider: oidc label: Authentik oidc: discovery_url: https://authentik.yourdomain.com/application/o/homepage/ client_id: your_client_id client_secret: your_client_secret scope: openid email profile
Verification Checklist
- Container health status:
1 2
docker inspect -f '' homepage # Expected: running
- API endpoint validation:
1 2
curl -I http://localhost:3000/api/health # Expected: HTTP/2 200
- Authentication flow test:
1
https://homepage.yourdomain.com → Redirect to Authentik → Successful return
Advanced Configuration
Security Hardening
- Context-aware access controls: ```yaml
config/access.yaml
groups: admin:
- ”.*” dev:
- “dev-.*”
- “test-.*” ```
- HTTP security headers via reverse proxy:
1 2 3 4
# Nginx configuration snippet add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;"; add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff;
Performance Optimization
- Caching strategies:
1 2 3 4 5
# homepage.yaml cache: enabled: true ttl: 5m cleanup: 15m
- Database tuning (for >100 services):
1 2 3 4 5
database: type: sqlite connection: /config/homepage.db busy_timeout: 5000 cache_size: -64000
Custom Service Definitions
Advanced Docker labeling strategy:
1
2
3
4
5
docker run -d \
--label homepage.name="Prod Database" \
--label homepage.group="Database" \
--label homepage.icon="database" \
postgres:15-alpine
Widget configuration to match:
1
2
3
4
5
6
7
8
- name: Databases
group: Database
icon: database
items:
- type: docker
label: $CONTAINER_NAMES
status: $CONTAINER_STATUS
stats: auto
Operational Management
Daily Maintenance Commands
Container health check:
1
docker exec homepage homepage check --config /app/config
Log inspection:
1
docker logs --tail 50 --timestamps homepage
Backup Strategy
- Configuration backup:
1 2
# Daily cron job tar -czf /backups/homepage-$(date +%F).tar.gz /opt/homepage/config
- Database snapshot:
1
docker exec homepage sqlite3 /app/config/homepage.db .dump > homepage.db.bak
Scaling Considerations
| Infrastructure Size | Configuration Approach |
|---|---|
| <25 services | Single-node deployment |
| 25-100 services | Separate DB volume |
| >100 services | HA PostgreSQL backend |
For large deployments:
1
2
3
4
5
6
7
database:
type: postgres
host: postgres.db.cluster
port: 5432
user: homepage
password: $DB_PASSWORD
name: homepage_prod
Troubleshooting Guide
Common Issues and Solutions
Problem: Containers not appearing in dashboard
Fix: Validate Docker labels and API permissions
1
docker inspect $CONTAINER_ID --format ''
Problem: Portainer controls not functional
Fix: Verify API key scopes
1
curl -H "X-API-Key: $PORTAINER_KEY" https://portainer/api/endpoints
Problem: Authentik redirect loop
Fix: Check OIDC configuration consistency
1
docker logs authentik | grep -i homepage
Performance Diagnostics
- Measure API response times:
1
curl -o /dev/null -s -w "%{time_total}\n" http://localhost:3000/api/services
- Database query analysis:
1
docker exec homepage sqlite3 /app/config/homepage.db "EXPLAIN QUERY PLAN SELECT * FROM services;"
Security Auditing
- Vulnerability scanning:
1
trivy image ghcr.io/benphelps/homepage:latest
- Authentication flow test:
1 2
curl -H "Authorization: Bearer $INVALID_TOKEN" http://localhost:3000/api/services # Expected: 401 Unauthorized
Conclusion
Implementing a professional-grade homepage dashboard transforms how you interact with your self-hosted infrastructure. By integrating gethomepage with Portainer and Authentik, we’ve created a unified control plane that provides:
- Operational efficiency through direct container management
- Security consistency with centralized authentication
- Situational awareness via service health monitoring
For further exploration:
The true power of this approach emerges as your environment scales - what begins as a simple dashboard evolves into an essential infrastructure management tool. With the foundation established in this guide, you’re equipped to extend these concepts to Kubernetes clusters, multi-node deployments, and custom service integrations.