Skip to content

Configuration

Environment variables

There is no .env file to create. Everything below has a working default and is set inline in docker-compose.yml, where you can see it in context.

VariableDefaultDescription
PORT3001Port the Express server listens on
NODE_ENVdevelopmentSet to production for production builds
DB_PATHdata/homepage.dbDatabase location; the data directory is derived from it
DOCKER_HOSTtcp://… address of a Docker socket proxy. Preferred over DOCKER_SOCKET — see Docker deployment
DOCKER_SOCKET/var/run/docker.sockDirect socket path, used only when DOCKER_HOST is unset
CORS_ORIGINSemptyExtra origins allowed to call the API cross-origin, comma separated. Empty means same-origin only
TRUST_PROXYtrueRead the client address from X-Forwarded-For. Set false only when there is no reverse proxy
HOMEPAGE_SECRET_KEY_FILEPath to a file holding the credential encryption key. See below
HOMEPAGE_SECRET_KEYThe key itself, as 64 hex characters. See below

Widget credentials are not environment variables

Every integration — Jellyfin, Weather, Umami, the rest — takes its credentials in the widget's own settings under Settings → Widgets, and the server stores them encrypted. There are no environment variables for them, and the old JELLYFIN_API_KEY / WEATHER_API_KEY fallbacks have been removed.

The credential encryption key

By default the key is generated into your data directory on first run and needs no configuration at all. Back it up with the database — losing it means re-entering every widget credential.

To keep it out of the data directory, the server checks these in order, and the first one it finds wins:

  1. /run/secrets/homepage_secret_key — where Docker and Podman mount a secret of that name. Declared in docker-compose.yml, so no environment variable is involved.
  2. HOMEPAGE_SECRET_KEY_FILE — any other path. The variable holds a path rather than the secret, so it is safe to write into a committed compose file.
  3. HOMEPAGE_SECRET_KEY — the key itself, for setups that prefer it.
  4. The generated data/.encryption-key.

Separating the key buys one thing: it protects a database file that travels without the rest of the data directory — an old snapshot, a copy pulled out for debugging. Credentials are already kept out of API responses, backup exports and git regardless of where the key lives.

Application settings

These are stored in the database (data/homepage.db) and are editable through the Settings panel.

SettingDescription
Homepage titleBrowser tab title and displayed heading
UsernameDisplayed in the header greeting
FaviconCustom favicon (upload via Settings → Preferences)
App logoCustom logo displayed in the header next to the title (upload via Settings → Preferences)
Clock format12h or 24h
Temperature unitC (Celsius) or F (Fahrenheit)
ThemeActive theme ID
Compact headerReduces header height
Header widgetsPin a widget (e.g. Search, Weather) to the left, centre, or right of the header
Bookmark category colourprimary, rainbow, or a fixed colour

Database

The SQLite database is created at data/homepage.db on first run. It stores:

  • Widget configurations and positions
  • Bookmarks and categories
  • Application settings
  • Themes (built-in + custom)
  • Keybindings
  • Backup settings

Backup & restore

Go to Settings → Backup to:

  • Create a manual backup (downloads a .db file)
  • Configure automatic scheduled backups
  • Restore from a previous backup

In Docker, mount the data/ directory as a volume so the database persists across container restarts:

yaml
volumes:
  - ./data:/app/data

Personal Homepage Dashboard