> ## Content Index
> Fetch the complete content index at: https://notes.d4rkcyber.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Homelab Dashboard
- URL: https://notes.d4rkcyber.com/homelab-dashboard-across-my-servers/
- Published: 2026-10-30T12:00:00.000Z
- Updated: 2026-10-30T12:02:46.000Z
- Description: How I use Homepage as a curated service directory across my homelab, with local Docker visibility and a clear distinction between links and remote container status.
- Author: David Dami
- Tags: homelab, access, dashboard, self-hosted

### One Place to Find Services Across My Servers

My homelab is spread across seven servers. When I need a dashboard, I want two things: a quick way to find the service I’m looking for, and a useful view of what is running. Homepage gives me the first across my setup, and it gives me Docker visibility on the host where it runs.

## Running containers by VM

Here is the running-container count per VM in this inventory snapshot. Together, these seven VMs account for 146 running containers:

- **ai-bruh:** 6
- **d4rkcloud:** 24
- **d4rkcloud-2:** 26
- **docker-vm:** 78
- **saitama:** 2
- **zabuza:** 9
- **citadel:** 1

## What the dashboard does

I run Homepage on `docker-vm`. Its service page is a curated directory rather than a generated list of every container. The current `services.yaml` has 99 configured link entries, grouped into areas such as infrastructure, networking, access, utilities, business and personal apps, automation, library, monitoring, and media.

That distinction is useful: a link tells me where to open an application; it does not necessarily tell me whether the remote container is healthy. I keep links for services across the homelab, but the Docker connection configured in Homepage points to the local Docker socket on `docker-vm`. It does not currently configure separate Docker endpoints for the other six servers.

## Configured service links

The live `services.yaml` contains 99 configured link entries across the Main and Media views. There are 97 distinct display names; repeated names are kept under their separate groups. This is the link directory, not a claim that every container has an individual card.

## Local Docker visibility versus remote links

The Homepage Compose service mounts `/var/run/docker.sock` into the container. Its `docker.yaml` registers that socket as the Docker provider. That lets Homepage read Docker information from `docker-vm`; it is separate from the service cards and links in `services.yaml`.

So I treat the page as a homelab index with local container integration—not as a complete multi-server container inventory. The other servers’ applications can be reachable from the dashboard as curated links, while their Docker status still needs to come from a remote provider or a separate monitoring view.

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

A service entry is defined separately. The URL below is a placeholder, not a live address:

```
# services.yaml — simplified example
- Monitoring:
    - Example Service:
        href: "<service-url>"
        description: "What this service is for"
        icon: "example.png"
```

## How I organize the page

The configuration splits the dashboard into a main homelab view and a media view. The main page groups infrastructure management, networking, security and access, utilities, my apps, data and AI, automation and backups, the library, and monitoring. The media page groups the media stack and its add-ons.

The layout settings use rows and columns so related services stay together. I also use Homepage widgets for selected systems—for example, resource usage, weather, and application status—rather than trying to turn every card into a monitoring panel.

```
# settings.yaml — simplified layout
layout:
  Main:
    style: row
    columns: 5
    tab: Main
    order: 1
  Media:
    style: row
    columns: 3
    tab: Media
    order: 2
```

## The cleaned Homepage Compose file

This cleaned Compose file keeps the active image, mounts, network, port, and environment variable names. The route hostname is a placeholder. I omitted the deployment-specific DNS resolver list so the article does not expose private network values. The local Docker socket is mounted so Homepage can read Docker information from its own server.

```
services:
  homepage:
    image: ghcr.io/gethomepage/homepage:v2.7.0
    container_name: homepage
    restart: unless-stopped
    group_add:
      - "988"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.homepage.rule=Host(`${HOMEPAGE_HOST}`)"
      - "traefik.http.routers.homepage.entrypoints=https"
      - "traefik.http.routers.homepage.tls=true"
      - "traefik.http.services.homepage.loadbalancer.server.port=3000"
    networks:
      - proxy
    ports:
      - "3000:3000"
    volumes:
      - ./config:/app/config
      - ./images:/app/public/images
      - ./icons:/app/public/icons
      - /var/run/docker.sock:/var/run/docker.sock
    env_file: .env
    environment:
      - NODE_OPTIONS=--dns-result-order=ipv4first
      - HOMEPAGE_VAR_TRAEFIK_USERNAME=${HOMEPAGE_VAR_TRAEFIK_USERNAME}
      - HOMEPAGE_VAR_TRAEFIK_PASSWORD=${HOMEPAGE_VAR_TRAEFIK_PASSWORD}
      - HOMEPAGE_VAR_PORTAINER_KEY=${HOMEPAGE_VAR_PORTAINER_KEY}
      - HOMEPAGE_VAR_PORTAINER_KEY2=${HOMEPAGE_VAR_PORTAINER_KEY2}
      - HOMEPAGE_VAR_ADGUARD_USERNAME=${HOMEPAGE_VAR_ADGUARD_USERNAME}
      - HOMEPAGE_VAR_ADGUARD_PASSWORD=${HOMEPAGE_VAR_ADGUARD_PASSWORD}
      - TZ=Europe/Dublin

networks:
  proxy:
    external: true
```

The host matcher uses a placeholder so the example can be adapted without copying a live hostname. The real configuration uses the host’s configured route.

## Keep dashboard credentials out of the service file

Homepage reads widget credentials from its environment. The example environment file lists the variable names used by this stack, but it contains no working credentials. I keep the real `.env` local and out of source control.

```
# .env.example — replace values locally; do not commit real credentials
HOMEPAGE_HOST=your-dashboard-hostname
HOMEPAGE_VAR_TRAEFIK_USERNAME=replace-locally
HOMEPAGE_VAR_TRAEFIK_PASSWORD=replace-locally
HOMEPAGE_VAR_PORTAINER_KEY=replace-locally
HOMEPAGE_VAR_PORTAINER_KEY2=replace-locally
HOMEPAGE_VAR_ADGUARD_USERNAME=replace-locally
HOMEPAGE_VAR_ADGUARD_PASSWORD=replace-locally
```

## A note about the Docker socket

The Docker socket is powerful: access to it should be treated as access to the Docker host, not as an ordinary read-only dashboard feature. In my current Compose file, the socket is mounted directly, without a read-only mount flag. That makes the Homepage container part of the trusted infrastructure, so I keep its access and network placement in mind when maintaining the stack.

## What I want from a homelab dashboard

For me, the value is not a wall of container names. It is a useful map of the services I actually use, organized so I can find the right one quickly, with status widgets where they add information. Homepage already gives me that navigation layer across the homelab and local Docker visibility on its own server.

The remaining distinction is important: a dashboard can link to an application on another server without discovering that server’s containers or health. If I want one page to show authoritative container state from all seven VMs, I need to add remote Docker visibility deliberately rather than assume the service links provide it.