docker compose setup for HomePage with Dashdot and Watchtower widgets from Komodo or Dockge, including detailing the dashboard setup for a multi-tab layout with four sections of content: system metrics, static content, dynamic applications (docker service discovery), and service monitors.
This post details setting up HomePage as part of a docker compose stack to create a service dashboard with system and service monitors, automatic service discovery (using Docker labels) and keyboard service search for QuickLaunch.
Â
Revision: 20250216-0 (init: 20240908)
Â
docker compose setup for HomePage with Dashdot and Watchtower widgets from Komodo or Dockge, including detailing the dashboard setup for a multi-tab layout with four sections of content: system metrics, static content, dynamic applications (docker service discovery), and service monitors.
Documentation is a crucial feature of a successful self-hosting methodology.
While migrating to Traefik and creating reverse proxies by adding dynamic configuration files or Docker labels, I documented the services’ map (on Notion, with multiple Table views).
A “Per Host” Table view (sorted by “Exposed Port”) for the services on one server is as follows:
Among the columns existing in the original Notion DataBase from which those views are created are:
Name: the service name — duplicates can exist if the service either uses multiple port (list all ports exposed) and/or is deployed on multiple Hosts
Host: the server name — a “single select” list of available servers
Exposed Port: any port exposed by the service, be it mapped to a reverse proxy or not
Slug base: the base URL to use for each domain (if multiple), for example, the home slug with the example.com domain; the full url is home.example.com
Domain mapping: for example.com, how the service is exposed via a reverse proxy (if it is): Traefik label, name of the Traefik dynamic yaml file, … if more than one domain, create as many “domain mapping” columns as needed
Per Domain, a “Added to “HomePage” checkmark as well as “Credentials stored in Password Manager” checkmark
Deployment Method: how the service is deployed, with entries from a mutli-selection list with content such as “Unraid”, “Dockge”, “Komodo”, “Docker Compose”, … i.e. make it easier to find the a given service in case of issues with it.
Tool URL: where to find documentation in case of an issue, often GitHub repositories.
Notes: Any notes relevant to the service; for example: “VNC-based, add /vnc.html to url”
Relationship: Notion DB allows linking components to other rows from the same table; for example, the “HomePage” service uses the “Docker Socket Proxy” service.
Automatic Discovery
Automation is another relevant component when attempting to maintain this knowledge map.
It is challenging to keep multiple sources of truth synchronized. As such, it is practical to have some components automatically announce themselves.
In the same way that adding an entry to Traefik can be done using Docker labels, the dashboard solution we retained, Homepage, can also automatically register Docker service using labels.
Homepage
A modern, fully static, fast, secure fully proxied, highly customizable application dashboard with integrations for over 100 services and translations into multiple languages. Easily configured via YAML files or through docker label discovery.
r/homelab and r/selfhosted are great places to discover people showcasing their “homepage dashboard.”
For this setup, we are using multiple features of the tool:
quicklaunch to start a service from the keyboard (no mouse click)
a layout to separate multiple sections: metrics, static, dynamic, and widgets
numerous instances to separate network definitions (or use various Traefik domains, for example, a domain1 for the local network and a domain2 for a reverse proxy for only some applications specific to Tailscale (where not all services are available on that domain2). When using tailscale, if using a local host as a subnet router, domain1 suffices.
Â
Here is what our local setup provides (yours will likely differ):
We will rely on homepage’s ability to perform Automatic Service Discovery using Docker labels. Those labels are homepage.group, homepage.name, homepage.icon, homepage.href, homepage.description, and instance-specific options.
The following are copy→adapt→paste options for a use-case with a single instance, multiple homepage instances, and an Unraid XML template filler. In each case:
replace example.com and example.net with the INSTANCE domain
replace ALIAS with the application name
replace TAB with the tab name as defined in the layout: section of your settings.yaml file
replace SIGN with the expected icon name.
replace SLUG with the base URL of the service you are connecting; it will be used with the domain name; for example, if the slug is home and the domain example.com, the href entry will be home.example.com
Replace INSTANCE1 and INSTANCE2 with the value you will use for your instanceName: (in the settings.yaml file)
do not add an entry if a service does not exist for a given instance
We have added the TAB in the .description field to sort when using homepage’s quicklaunch option easily. It is also possible to use the host in that location. However you decide to use those, they are methods to differentiate multiple instances using a similar .name-base on different hosts, for example.
Although the Unraid WebUI allows you to manually “Add” labels for each required label, you can also modify the Docker service’s XML file.
Those are in the /boot/config/plugins/dockerMan/templates-user folder and are named my-<SERVICE>.xml. Once the matching service entry is found, it can be edited by copying and adapting the following lines before the final </Container> line:
After modifying the XML file, from Unraid’s “Docker” tab, Edit the Service and undo any changes to enable the Save button. Save-ing will restart the updated service.
Preliminary installations
We will deploy services using docker-compose. Although tools such as Dockge or Komodo are not a requirement, they provide a convenient method to deploy “stacks.” Please see the Dockge post for additional details on previous stack deployments.
Our example configuration files, in particular, will show how to integrate Dashdot and Watchtower (with metric collection) as widgets and automatically discover Docker services. Both were installed following the instructions in that post.
Since the tool does not provide a WebUI, no labels are present for the homepage. No other labels are added either; extend as needed.
We also do not include any environment variable to cover the user of shoutrrr notifications as the choice of method is left to the end user. Should you decide to use it, please adapt the following additional content for your environment: section as needed based on the list of available notification services (environment variables for API keys and such are recommended):
Although we are not describing how to set reverse proxy configurations for those, in the further configuration steps, we will rely on the following two URLs for those services:
Glances is a top/htop alternative with a potential WebUI and can integrate directly within HomePage. Dashdot appears to have an issue providing accurate information about GPU Load and Memory. We will use glances to report GPU information (GPU model, memory utilization, load, and temperature).
Follow the link to the proposed compose.yaml file. This will run the Nvidia-compatible container in WebUI (-w) mode on port 61208, as watchtower to update it, use traefik labels to expose an HTTPS URL (compatible with the Redis provider), and use labels to configure the homepage.
After starting the container, we must obtain the name of the local GPU, as seen by Glances, using curl http://localhost:61208/api/4/gpu, and note its value. In our case, it was nvidia0. This value will be used in Homepage’s service.yaml.
Docker Socket Proxy
Docker Socket Proxy “is a security-enhanced proxy for the Docker Socket” that limits access to user-selected details. Unless you have used it for other setups (such as installing Traefik), it is only heplful when using Homepage with tabs from more than a single server. We will proceed considering it was installed for our setup.
This setup will allow containers from hosts other than the one starting Homepage to be self-discovered by Homepage from any server host. It is only to be used within a non-internet-exposed local network. Even with this limitation, it is also recommended to add firewall rules to only allow connection to the exposed port from the authorized Homepage host’s IP. We will not use the tool using the privileged flag and will only share the docker socket as ready-only so the connection can not perform any action on the running container.
Follow the link to obtain our proposed compose.yaml. The only access we grant ourselves is a read capability on CONTAINERS, which allows us to get their status, usage, and access to their labels (among other things) so we can display that information in Homepage (and be used by Traefik).
Homepage installation
We deploy Homepage using docker compose (manually or through Dockge or Komodo). It is also available on Unraid or Kubernetes. After creating the stack, create a config directory within the stack directory (/opt/stacks/homepage if using Dockge or your installation path when using Komodo, for example,/opt/komodo/stacks/homepage/config); the first run will have Homepage populate this directory with default files.
Our proposed compose.yaml uses homepage.-specific labels to integrate Homepage’s Docker within our dashboard. Our file looks as follows:
services:
homepage:
image: ghcr.io/gethomepage/homepage:latest
container_name: homepage
ports:
- 33009:3000 # changing the default exposed port to 33009
volumes:
- ./config:/app/config # Make sure your local config directory exists
- /var/run/docker.sock:/var/run/docker.sock:ro # remove if using Docker Socket Proxy, as seen in our configuration file
- /tmp:/mountpoint:ro # a mountpoint to a disk that we want to monitor the available size of using the "resources" widget (in widgets.yaml)
labels:
- com.centurylinklabs.watchtower.enable=true # update with Watchtower
- traefik.enable=true # (optional, remove if not using Traefik) This configuration follow the instructions set in the corresponding blog post
- traefik.http.routers.home.entrypoints=https # HTTPs upgrade
- traefik.http.routers.home.rule=Host(`home.example.com`) # here we are only providing the "main" homepage instance
- homepage.group=host_dynamic # The layout uses the group to place content. We use the host_ entry to separate the tabs
- homepage.name=Homepage # name of the application
- homeage.icon=homepage.png # You can also use complete URLs for icons
- homepage.instance.main.href=https://home.example.com/ # "main" instance behind a reverse proxy
- homepage.instance.alt.href=https://home.example.net/ # "alt"-ernate instance behind a reverse proxy
- homepage.description=HomePage (host) # Can be used to provide "quick launch" search content; having the host listed makes it simpler to find the right instance of a software in a multiple machine deployment
(If using Komodo, in the volumes: section, replace ./ with the full path location)
To use a local icon, first create a Docker mount to /app/public/icons and then reference your icon as /icons/myicon.png. You will need to restart the container when adding new icons.
To use a remote icon, use the absolute URL (e.g. https://...).
Â
After starting (or docker compose up -d) the stack, a few files will be added within the config folder:
The settings.yaml file allows you to define application level options. For changes made to this file to take effect, you will need to regenerate the static HTML, this can be done by clicking the refresh icon in the bottom right of the page.
Within our proposed docker.yaml file, we are using the “Docker Socket Proxy” exposed to the LAN (in read-only mode), with a server’s IP of 192.168.22.11 (adapt as needed). We are naming it tab1-docker (multiple entries can be added if using multiple tabs). Commented in the file are other methods to access the docker information if the homepage is running on the host where the docker services are running. This is needed for the Automatic Service Discovery of Docker services.
widgets.yaml
Our proposed widgets.yaml file’s content will be displayed at the header of every Homepage call. We want it to display information on the homepage’s hosting system resource details (CPU, memory, disk usage), a search box, the current time, and the weather.
Our proposed settings.yaml file contains only one tab definition. Adding tabs can be done using the tab: name within the layout: section. This layout uses tabs to separate items, either per server or purpose, at the user's discretion. tab1 has four distinct sections: a tab1_metrics that will display Dashdot widgets as well as Glances (for GPU), a tab1_static section to add services (either not started as containers and not including the homepage. labels, or additional user-controlled entries), a tab1_apps section where the Automatic Service Discovery of Docker services is performed, and a tab1_monitors where we will display additional widgets, here the Watchtower service widget.
This file is also set to be used as the main instance (on example.com), using 5-columns and with quicklaunch enabled so that services can be started by starting to type their name or description.
services.yaml
Our proposed services.yaml file defines three of tab1's four sections ordered as in the layout: section of the settings.yaml file:
tab1_static for entries not accessible from Docker’s Automatic Service Discovery, either because those are not Docker containers or because the service was started with no Homepage labels:. For an illustration of Homepage’s capabilities, in our example, we are using Dockge itself as discovered by the actual container name as running on the tab1-dockerserver:.
tab1_metrics has five metrics columns: four provided within the iframe from the Dashdot service setup earlier and one GPU column coming from Glances.
The tab1_apps are omitted from this file. They are automatically added from Docker’s “Automatic Service Discovery” for all containers using the tab1_appslabels: entry (from any server defined in docker.yaml). As discussed earlier, this setup uses tabs to classify applications either per server or per purpose.
tab1_monitors contains another service widget; here, we are using the Watchtower service to inform us of “Scanned” or “Updated” container images.
Configuration results
Using the default configuration files we proposed (with the example.com URLs), loading the Homepage URL shows a functional page with no content (the GPU monitor is not using Glances in this view, and none of the example.com URLs are reachable):
Â
With a few tweaks:
Configuring the tab1-docker in docker.yaml
Modifying the example.com to reflect our internal domain
Uncommenting the first section from tab2's layout: in settings.yaml (done here for illustration purposes to show tab2)
Extending the tab1_static section to manually include the Komodo stack, which was used to deploy the main instance of Homepage
Where we can find the different sections of our setup:
The “informational widgets” use the content from the widget.yaml
The settings.yamllayout: with tab1 and its four sections (in a 5-columns setup):
tab1_metrics as defined in the services.yaml file
tab1_static (also defined in services.yaml)
tab1_apps is automatically populated from any Docker services (as found on all the servers defined in the docker.yaml file) using the homepage.group=tab1_appslabels:
tab1_monitors as specified in the corresponding section of the service.yaml file
The content of the bookmarks.yaml (which we have not altered) is present at the end of each page. This is because we have not defined its location per the layout: we defined in settings.yaml. By default, un-anchored content is displayed on all pages.
The following are best practices from using Unraid for close to three years. Although much more complex installation (with ZFS pools or complex alternate OSes VM setup) are possible, it is written to support people interested in learning about the tool. I wrote about Unraid in the past, such as “Things I wished I had READ before my first Unraid Install... and more”. This post is different as I have recently installed a new workstation; and used the experience to document various aspects such as installation, array management, share configurations, and community applications.
I hope it provides valuable insights to benefit those interested in exploring Unraid further, especially as the 7.0 version is coming soon. We note that we will use external links to Unraid’s documentation for additional content on discussed topics.
This guide details how to deploy Traefik using Docker compose (with Dockge) and Cloudflare as our DNS Challenge provider to generate Let’s Encrypt certificates for local infrastructure (not internet-accessible) and use basic authentication to protect the Traefik Dashboard. The configuration files presented can also be used with other deployment methods, such as Unraid.
Linux host set-up instructions for Dockge, a self-hosted Docker Compose stacks management tool with a feature-rich interface for self-hosting and home lab setups. It provides access to an all-in-one view of logs, a YAML editor, a web terminal, container controls, and monitoring.