New releases
Recipe version compared with the latest known upstream release. A version number, not a reading of what changed.
Homepage brings service links, bookmarks, and optional integration widgets into a configurable home dashboard. This recipe enables password login, restricts accepted hosts, runs as an unprivileged user, and keeps configuration on your server.
Homepage is a configurable landing page for a home server. Group services, keep useful bookmarks, search them with Quick Launch, and add optional service widgets. It suits operators who prefer YAML configuration over a database-backed portal.
The starter links point to this dashboard and official public documentation. Replace them with your own service URLs in config/services.yaml; they do not install the linked applications. The dashboard complements service monitoring rather than replacing it.
As of v2, upstream includes password or OIDC authentication. This recipe enables one shared password and a random session secret. OIDC is available but not configured. There are no separate user permissions, native SAML or native MFA in this recipe. An identity provider may add MFA externally.
All dashboard YAML, custom CSS/JavaScript and logs live in the mounted configuration directory. No database, Docker socket, Kubernetes credentials, API keys or cloud account are required. Resource widgets see the container’s environment. Search can contact the provider you select when you submit a query.
Homepage can replace the service-link part of start.me for a homelab, but does not reproduce its cloud collaboration features. Its upstream repository includes GPL version 3; the image label still says Apache-2.0, so use the repository LICENSE as the recorded source for this page.
Official sources: installation and authentication, configuration, Docker, v2.7.0 source.
Security assessment (2026-10-24): password gate enabled, loopback bind, non-root process and no Docker socket. Public access still needs HTTPS and edge login protection. This is a configuration review, not an image vulnerability scan.
These are stored results of separate checks, not real-time data. An unknown status means the check has not been performed yet.
Recipe version compared with the latest known upstream release. A version number, not a reading of what changed.
Result of a dedicated Docker image scan, not a Compose configuration check.
A new major version is found by comparing version numbers. A compatibility verdict is entered by hand after reading the release notes and the migration steps.
Upstream Compose changes relative to the verified recipe.
Pinned image tags checked for newer versions.
From observation to action
The recipe already pins the latest known release. The steps below show the evidence retained for that version.
v2.7.0v2.7.0Open this release on GitHub ↗ The link is evidence to review, not proof of compatibility.
The version numbers do not cross a major compatibility boundary. No compatibility verdict has been recorded.
No image-tag change is currently planned.
Change the tag and restart. Release-specific migration steps still come from the release notes and installation guide.
No version change is currently planned. The recipe includes a backup procedure. Restore has been tested.
An exact Fully verified check for this target was recorded on 2026-10-24.
The status shows how fully the published recipe meets each level's requirements.
A minimal setup for a local network or access through a VPN.
The recipe covers every requirement at this level.
A public deployment with protected access and backups.
The recipe covers every requirement at this level.
A setup designed for predictable operations and observability.
You still need to add: separate database, external monitoring, cpu and memory limits.
Tailored to your server
Answer five questions and download a ready-to-run Homepage bundle.
Read the full guide first: it explains external access, backups, and data locations.
cp .env.example .envdocker compose up -ddocker compose psUse Ubuntu 24.04 LTS or Debian 12/13, Docker Engine and Docker Compose >=2.24.0. Install Docker from its official repository, including the Compose plugin. Download the complete recipe, including config/.
cp .env.example .env
chmod 600 .env
openssl rand -hex 24
openssl rand -hex 32
Put the first random value in HOMEPAGE_AUTH_PASSWORD, the second in HOMEPAGE_AUTH_SECRET; replace the CHANGE_ME placeholders; do not leave either empty. Configure the URL and host list, then start:
docker compose config --quiet
docker compose pull
docker compose up -d --wait
docker compose ps
Visit http://localhost:3000, enter the password, then edit YAML files in config/. The initializer changes ownership to UID/GID 1000; use sudo to edit if needed. Restart homepage after changes. The configuration is shared by every signed-in visitor.
Use a domain, HTTPS, firewall and encrypted off-server backups. Leave port 3000 on loopback and expose only the reverse proxy. Keep the login behind a VPN/IP allowlist or apply an edge password-attempt limit: Homepage has no native rate limiter. The Nginx example includes such a limit; the Caddy and Traefik examples require that protection separately.
The default bind is loopback. Prefer an SSH tunnel (ssh -L 3000:127.0.0.1:3000 user@server) or a VPN/proxy. To bind to a trusted LAN, explicitly change the published address in Compose and restrict it with the firewall. Set the exact browser origin in HOMEPAGE_EXTERNAL_URL and its host:port in HOMEPAGE_ALLOWED_HOSTS. Never use * as the host list.
For https://home.example.com, set HOMEPAGE_EXTERNAL_URL=https://home.example.com and HOMEPAGE_ALLOWED_HOSTS=home.example.com. Restart to apply. The URL determines secure session cookies, so it must match the actual browser address.
Use proxy/Caddyfile on the host after configuring DNS. Caddy obtains TLS automatically. Add a VPN/IP restriction or an independently configured login-attempt limit.
Use proxy/nginx.conf, obtain its certificates first, and run sudo nginx -t before reloading. Its limit_req_zone belongs in the http context. The credential callback is limited to five requests/minute with a burst of five. Adapt the value to your users and monitoring.
Load proxy/traefik.yaml through the file provider with the websecure entry point and letsencrypt resolver. It assumes Traefik runs on the host; a container cannot use the host’s loopback without suitable networking. Add a VPN/IP restriction or edge login protection.
HOMEPAGE_CONFIG_DIR (default ./config) is mounted at /app/config, including settings, service links, bookmarks, widgets, custom files and logs. Use an absolute path when moving the recipe. Do not share it with another app. There is no database. Preserve custom icons placed inside this directory if referenced by your configuration.
Every .env.example setting:
| Variable | Meaning |
|---|---|
HOMEPAGE_VERSION |
Pinned application image tag, initially v2.7.0 |
HOMEPAGE_PORT |
Host loopback HTTP port, initially 3000 |
HOMEPAGE_CONFIG_DIR |
Configuration directory; initializer makes it owned by 1000:1000 |
HOMEPAGE_ALLOWED_HOSTS |
Comma-separated exact browser hosts, including nondefault ports |
HOMEPAGE_EXTERNAL_URL |
Actual browser origin including scheme and optional port |
HOMEPAGE_AUTH_PASSWORD |
Strong shared dashboard password; required |
HOMEPAGE_AUTH_SECRET |
Random session secret, at least 32 characters; required |
TZ |
Container timezone, initially Etc/UTC |
HOMEPAGE_BACKUP_DIR |
Optional private destination for backup.sh |
Rotate the password or secret in .env and recreate the service. Keep secrets out of custom CSS/JavaScript and static assets, which remain public. Widget API credentials need least privilege. Docker/Kubernetes discovery and OIDC are not enabled by this recipe.
bash backup.sh
The script stops the writer, archives the complete config directory, .env and Compose, then restores its previous running/stopped state. Archives have mode 600. Copy them off-server and encrypt them: widget keys and authentication secrets may be inside. Backups exclude the image’s ephemeral cache and browser local storage. Copy separately any custom assets stored outside the config directory.
Restore replaces all current configuration. Use only your own trusted archive. Start the recipe once to create its container/mount, compare the archived configuration.env manually with your current .env, and keep the application version consistent. The archived environment is not automatically executed or activated.
bash restore.sh /safe/path/homepage-backup.tar
The script checks required configuration files before stopping the service, takes a safety backup, replaces the config directory and waits for health. If extraction fails, it keeps the service stopped. Sign in and verify service links and bookmarks. Restoring the old session secret may reactivate still-valid old cookies; rotate it if needed.
Read upstream release notes, back up, set the new explicit HOMEPAGE_VERSION, then run docker compose pull && docker compose up -d --wait. Never use latest. Verify login and each integration. The documented recipe update is an in-place image replacement; review future major-release instructions before adopting them.
Stop homepage, restore the previous pinned tag in .env, pull it, start once, then restore its pre-update archive with restore.sh. Compare the saved environment and test login/widgets. Homepage has no database migration in this recipe, but newer YAML options may not work with an older version: restore matching configuration rather than keeping newer files.
docker compose down removes containers/networks and keeps bind-mounted configuration. For permanent removal, first export a backup, run docker compose down --volumes, and explicitly remove only your chosen HOMEPAGE_CONFIG_DIR and private .env after checking the absolute paths. This destroys configuration and any widget keys inside it. Remove DNS/proxy rules and backups separately when no longer needed.
Official authentication guidance explains the password/OIDC gate, public static files, Host guard and absence of native login rate limiting.
Tell us how it went on your server
Opens a prefilled GitHub issue. A GitHub account is required; submitting the issue makes it public.
docker compose ps
docker compose logs --tail=100 homepage
docker compose config --quiet
curl -fsS http://127.0.0.1:3000/api/healthcheck
Host validation failed: allow the exact browser host, including its port, in HOMEPAGE_ALLOWED_HOSTS. Do not use a wildcard. Health using the internal 127.0.0.1:3000 host does not prove that the external host works.
Login loops or missing cookies: HOMEPAGE_EXTERNAL_URL must match the browser’s scheme and address. HTTPS creates secure cookies that cannot work through HTTP. Recreate the container after changing .env.
YAML error or missing links: check indentation in settings/services/bookmarks/widgets. Bookmarks have an extra list around href; services use an object. Restart after changes. Invalid configuration can break the dashboard while health still succeeds.
Permission denied: UID/GID 1000 needs access to config and logs. The initializer recursively changes ownership; never point it at a system directory or another application’s data. NFS/root-squash may need storage-side permissions.
Broken widget: its URL must be reachable from the container; localhost means Homepage itself. Verify least-privilege token permissions. The recipe connects no Docker socket or Kubernetes credentials and does not install linked applications.
Repeated password attempts: limit the credential callback at the proxy or use a VPN/IP restriction. Logs include Failed password sign-in attempt; do not publish configuration dumps containing secrets.
Backup/restore: use the complete recipe and its .env; FOSSARY_ENV_FILE selects another environment file. Archives contain secrets. Failed extraction leaves the service stopped: inspect logs, free space, permissions and the safety archive before retrying. Start the recipe once on a new machine before restore.
Fossary is an independent informational catalog and is not affiliated with the developers of the listed applications. We collect information from public sources and verify published recipes, but we do not develop, distribute, or control these applications.
A listing or validation status is not a requirement, endorsement, or personal recommendation to use an application. You decide whether it is suitable and use it at your own risk. We do not warrant an application's security, availability, or fitness for purpose and, to the extent permitted by law, are not liable for resulting loss or damage. Review its license, security settings, data processing, and backup procedures before installation.