From 3c2f03d1303eed35b44b67b73e908e03b1c34107 Mon Sep 17 00:00:00 2001 From: Goyban Date: Mon, 7 Sep 2026 10:41:55 +0200 Subject: [PATCH] added Heimdall Documents ALLOW_INTERNAL_REQUESTS=false, which blocks enhanced-app lookups to private IPs by default and makes every LAN tile fail silently. Also that the data dir holds the API keys of every enhanced app. --- heimdall/.env.example | 29 +++++++++++++ heimdall/README.md | 96 +++++++++++++++++++++++++++++++++++++++++++ heimdall/compose.yaml | 14 +++++++ 3 files changed, 139 insertions(+) create mode 100644 heimdall/.env.example create mode 100644 heimdall/README.md create mode 100644 heimdall/compose.yaml diff --git a/heimdall/.env.example b/heimdall/.env.example new file mode 100644 index 0000000..d8a88c6 --- /dev/null +++ b/heimdall/.env.example @@ -0,0 +1,29 @@ +# Copy to .env and adjust. .env is git-ignored; this file is not. +# +# compose.yaml currently writes these as bare ${PUID} / ${PGID} / ${TZ}, +# with no defaults, so a clone without a .env starts the container with +# empty values instead of failing. Set all three -- or add `:-` defaults +# to compose.yaml, which is what the rest of this repo does. + +# ─── Identity ─────────────────────────────────────────────────────── +# Must own the data directory, or Heimdall can't write its database. +# id -u ; id -g +PUID=1000 +PGID=1000 +TZ=Europe/Paris + +# ─── Paths ────────────────────────────────────────────────────────── +# Mounted at /config. Holds the SQLite database, uploaded icons, the +# nginx config -- and the API keys of every "enhanced" app you add. +# Back it up; never commit it. +#DATA_PATH=./data + +# ─── Ports ────────────────────────────────────────────────────────── +#PORT=4080 +#HTTPS_PORT=4043 + +# ─── Reaching your own LAN ────────────────────────────────────────── +# NOT set in compose.yaml, and the one you will most likely need. +# Heimdall blocks enhanced-app lookups to private/reserved IPs by +# default -- which is every service in your house. See the README. +#ALLOW_INTERNAL_REQUESTS=true diff --git a/heimdall/README.md b/heimdall/README.md new file mode 100644 index 0000000..bf55a29 --- /dev/null +++ b/heimdall/README.md @@ -0,0 +1,96 @@ +# Heimdall + +A start page for everything else in this repo. Tiles that link to your services, +and for some of them an "enhanced" tile that polls the app's API and shows +something useful on the face of it — disk free, active downloads, unread count. + +Actively maintained, despite its age: v2.8.3 landed in September 2026. + +## Quick start + +```bash +cp .env.example .env +$EDITOR .env # PUID/PGID/TZ have no defaults in compose.yaml +docker compose up -d +``` + +Open `http://:4080`. There is no login and no setup wizard — you get an +empty dashboard, and everything is configured by clicking around. Read the +security note below before you put anything on it. + +## Ports + +| Host | Container | Purpose | +|------|-----------|---------| +| 4080 | 80 | Web UI | +| 4043 | 443 | Heimdall's own HTTPS listener — see gotchas | + +## Why it looks like this + +**The LinuxServer image**, same reasoning as [jellyfin](../jellyfin/README.md): +`PUID`/`PGID`/`TZ`, `/config`, s6, one rebuild cadence. For a service this small +the win is that it behaves like everything else on the box. + +**`./data` mounted at `/config`.** The names disagree because the repo's +convention is `data/` on the host and the image's convention is `/config` in the +container. Whatever it's called, it is the entire service: the SQLite database, +uploaded icons, the nginx config, and the API keys of every enhanced tile. + +**Nothing else.** No database container, no cache, no environment variables +beyond the LinuxServer three. This is one of the genuinely simple stacks — which +is why the interesting content below is about what Heimdall *doesn't* tell you. + +## Gotchas + +- **Heimdall blocks requests to your own LAN by default.** This is the one that + wastes an afternoon. Enhanced tiles — the ones that show live data — make a + server-side request to the app's API, and the image ships + `ALLOW_INTERNAL_REQUESTS=false`, which refuses lookups to private or reserved + IP addresses. Every service in your house is on a private address, so every + enhanced tile fails, and the tile just sits there looking broken. Add + `ALLOW_INTERNAL_REQUESTS=true` to the environment block. It is not in + `compose.yaml` today. +- **There is no authentication out of the box.** Anyone who reaches port 4080 + gets a map of your entire infrastructure, with working links. Heimdall can + password-protect itself, or you can put basic auth in front via the image's + nginx: + ```bash + docker exec -it heimdall htpasswd -c /config/nginx/.htpasswd + ``` + then uncomment the basic auth lines in `/config/nginx/site-confs/default.conf` + and restart. Better still, put [Authentik forward + auth](../docs/authentik-sso.md#forward-auth--putting-an-app-with-no-sso-behind-authentik) + in front — a dashboard is the textbook case for it, since it has no accounts + worth integrating and every client is a browser. +- **Enhanced tiles store API keys in the data directory.** That's a Sonarr key, + a Nextcloud token, whatever you connected. `data/` is git-ignored by this + repo's deny-by-default rule — verified — but it means the directory is a + credential store, not just cosmetics. Back it up accordingly, and don't paste + it into a gist when asking for help. +- **Port 4043 is Heimdall's own TLS**, with a self-signed certificate. In this + repo TLS terminates at the proxy, so the mapping is redundant — drop the line + unless you're reaching it directly and are willing to click through the + warning. +- **`${PUID}`, `${PGID}` and `${TZ}` are bare.** No `:-1000` defaults, so a + clone with no `.env` gets empty strings and starts anyway — confirmed: + Compose emits `The "PUID" variable is not set. Defaulting to a blank string.` + and carries on. The rest of this repo writes `${PUID:-1000}`. +- **`:latest`.** Heimdall ships real releases (`2.8.3`, `v2.8.3-ls363`); pin one + if you'd rather not be surprised. +- **Back up `data/`.** Rebuilding a dashboard by hand is an hour you won't enjoy, + and the icons you uploaded aren't anywhere else. + +## Exposing it + +- [Reverse proxy with Caddy](../docs/reverse-proxy.md) — the normal route; use + port 4080 and ignore 4043. +- [Single sign-on with Authentik](../docs/authentik-sso.md) — **strongly + recommended if this leaves the LAN.** Forward auth is the right fit: no + accounts to map, browser-only clients, and it stops the dashboard being a + directory of your network for anyone who finds it. +- [Cloudflare Tunnel](../cloudflare-tunnel/) — fine, it's a small HTML page. + +## Links + +- Upstream: +- Image: diff --git a/heimdall/compose.yaml b/heimdall/compose.yaml new file mode 100644 index 0000000..c47ee3f --- /dev/null +++ b/heimdall/compose.yaml @@ -0,0 +1,14 @@ +services: + heimdall: + image: lscr.io/linuxserver/heimdall:latest + container_name: heimdall + environment: + - PUID=${PUID} + - PGID=${PGID} + - TZ=${TZ} + volumes: + - ./data:/config + ports: + - 4080:80 + - 4043:443 + restart: unless-stopped