Infrastructure guide
Homepage Docker Compose: Private Access, Host Checks, and Safe Widgets
Deploy Homepage privately with persistent configuration, precise allowed hosts, deliberate widget permissions, and a recovery plan.
Published and reviewed by OpenAlt · October 7, 2026

Run Homepage privately, persist its configuration, and add integrations only after you understand what they can reveal. A useful dashboard should help you reach your services without becoming another public route into them. Start with ordinary links; earn the complexity of live widgets later.
This guide uses official documentation checked on October 7, 2026. It describes a cautious installation and acceptance process, not a performance benchmark. If nobody can maintain another service, a shared bookmark collection may already solve the problem.
Table of contents
- What should the dashboard be allowed to do?
- How do you start a private Compose installation?
- How do you fix host validation correctly?
- How should links and widgets be configured?
- Does Homepage need the Docker socket?
- How do you protect remote access?
- How do you back up and update the dashboard?
- FAQ
What should the dashboard be allowed to do?
Give Homepage only the access needed to answer the questions its readers actually ask. A link to a service and a widget that reads the service's API have different consequences when the dashboard is exposed.
Homepage's service configuration separates link destinations from integrations and monitoring. Write down the intended audience before adding credentials: just you, your household, or a team. A household member may need a media link without needing infrastructure names, storage details, or administrative status.
Our recommendation is to begin with three useful destinations and no API credentials. Ask another intended reader to find a service. If they cannot recognize its name, improve the label before adding graphs. Use descriptions such as “Family photographs” rather than internal container names.
The OpenAlt self-hosted directory helps you identify the services worth operating. Treat the dashboard as navigation for those decisions, not an incentive to install everything that has a supported widget.
How do you start a private Compose installation?
Persist /app/config and bind the web port to loopback for the initial trial. The official Docker instructions document the project image and port 3000; the configuration below deliberately omits Docker integration.
Create a project directory, create its config subdirectory, and save this as compose.yaml:
services:
homepage:
image: ghcr.io/gethomepage/homepage:latest
ports:
- "127.0.0.1:3000:3000"
environment:
HOMEPAGE_ALLOWED_HOSTS: localhost:3000,127.0.0.1:3000
volumes:
- ./config:/app/config
restart: unless-stopped
Run docker compose up -d, then open http://localhost:3000 on the Docker host. For a remote Linux host, use an SSH tunnel instead of assuming your laptop's localhost reaches the server. Confirm that the generated configuration files appear in the host directory.
The moving latest tag is convenient for this initial trial. Before depending on the dashboard, record the tested image digest and choose a deliberate update policy. Recreating a container should not erase your configuration or silently change the software version during an unrelated repair.
Check filesystem ownership if Homepage cannot write its files. Avoid solving every permission error with globally writable directories; first establish which user runs the container and which directory the mount actually references.
How do you fix host validation correctly?
Allow the exact hostname and port through which you reach Homepage. Do not replace the allowlist with a wildcard merely to make an error disappear.
The installation reference explains HOMEPAGE_ALLOWED_HOSTS, introduced in version 1.0. Values are comma-separated without spaces. When an access attempt fails validation, compare the hostname recorded in the application log with the browser address and proxy configuration.
Use this troubleshooting order:
- Confirm the private loopback installation still opens.
- Check the exact hostname presented through the chosen remote route.
- Add only that intended host to the environment setting.
- Recreate the service so the environment change takes effect.
- Repeat the test from the real client device.
Keep host validation separate from authentication. Allowing a domain means the request has an acceptable host header; it does not mean the person sending it is authorized to see the dashboard. A proxy can also forward an unexpected host even when DNS points to the correct machine.


How should links and widgets be configured?
Make the browser link work first, then test any server-side widget separately. A successful click does not prove that the Homepage container can reach the API used by a widget.
For a first entry, save this in config/services.yaml:
- Resources:
- OpenAlt:
href: https://openreplace.com/self-hosted
description: Find self-hosted software and deployment tradeoffs
The bookmarks documentation offers an even simpler bookmarks.yaml option when all you need is navigation. Choose the simplest form that communicates the destination clearly. A dashboard with a few dependable links is more useful than one full of broken status indicators.
For live integrations, the browser and container may use different addresses. Docker's Compose networking documentation explains service-name discovery on shared networks. Inside Homepage, localhost means that container, not a different application or your laptop.
Add one widget at a time. Verify its endpoint, credentials, permissions and displayed fields before moving on. Keep API credentials out of publicly shared configuration examples. If an integration supports narrowly scoped credentials, grant only the operations it needs.
Does Homepage need the Docker socket?
No. Ordinary links and many service integrations work without direct access to the Docker daemon. Leave the socket disconnected until a concrete feature requires it.
Homepage's Docker integration guide describes a restricted socket proxy and shows POST=0 to deny write requests. This is a separate control from mounting a socket with a read-only filesystem flag; the latter does not define which API requests may travel over the socket.
Before adding a proxy, identify the exact information you want: container status, a service health check, or application-specific data. These are different questions. A running container can still serve an error page, and a healthy website does not require access to its container daemon.
Keep the proxy on a private network and enable only the endpoints the integration needs. Document who can reach that network. If understanding these permissions feels disproportionate to a small status badge, omit the badge. The Portainer guide explains the similar responsibility attached to managing Docker through another web interface.
How do you protect remote access?
Choose a private VPN or an authenticated HTTPS entry point, then verify access with a signed-out browser. Do this before connecting widgets that reveal personal or operational information.
Current Homepage security documentation describes password or OIDC authentication from version 2.0. It requires a signing secret of at least 32 characters and warns that password attempts are not rate-limited by the application. Follow the documentation for your installed version rather than mixing newer authentication settings into an older image.
For an Internet-facing route, configure TLS, authentication and appropriate rate limiting at the access layer. Verify that the container's direct port cannot bypass that layer. The Caddy Compose guide covers the proxy foundation; a working certificate alone is not the entire access policy.
Test from a device outside the trusted network. Check both the initial page and widget responses. Finally, revoke a test credential and confirm that access stops. Write the recovery procedure somewhere reachable without the dashboard itself.
How do you back up and update the dashboard?
Back up the configuration, deployment definition and necessary secrets through your normal protected backup process. Restore them into a private test instance before relying on a rebuild during an outage.
Docker's volume documentation distinguishes persistent storage from a container's writable layer. In this guide the configuration uses a host bind mount, so explicitly include that host directory in your backup selection.
Before updating, keep a working configuration copy and record the current image identity. After updating, check navigation, authentication, host validation and each credentialed widget. If a widget breaks, isolate that integration before rolling back unrelated services.
A useful acceptance record is short: date, image, backup location, tested client, and any disabled integration. Keep it with the operating notes. Another person should be able to restore the dashboard without reconstructing every decision from memory.
FAQ
Why does Homepage say the host is not allowed?
The incoming hostname or port does not match the configured allowlist. Check the log and add the intended host precisely rather than disabling validation.
Must I mount the Docker socket?
No. Start without it. Add a restricted integration only when container information provides a clear benefit.
Why does a link work while its widget fails?
The browser opens the link, while the widget may call its API from the container. Check that second network route and its credentials.
Can I move Homepage to another server?
Yes, by preserving configuration and necessary secrets, then checking permissions, host settings and integration addresses on the new host before switching users over.