xinghelee/DockerView

Editorial-style index page for your homelab — auto-discovers Docker containers and renders them as a clickable directory.

★ 0Forks 0TypeScriptGitHub ↗Compare

README

DockerView

Auto-discovers Docker containers on your home server and renders them as an editorial-style index page. One container, mounts the Docker socket read-only, lists everything that's running. Click a service to open it.

Run it

With Docker Compose (the way you'll deploy)

cp overrides.example.json overrides.json    # one-time, even if you don't edit it
docker compose up -d --build
# open http://<your-host>:8787

The cp is important: the compose file bind-mounts ./overrides.json into the container. If the file doesn't exist, Docker silently creates an empty directory with that name, and DockerView will run with zero overrides.

Local dev (Bun)

bun install
DOCKERVIEW_MOCK=1 bun run dev   # frontend at :5173, API at :8787

DOCKERVIEW_MOCK=1 runs against the bundled sample data — useful when you don't have Docker locally or just want to play with the UI.

Two ways to decorate cards

You can polish each service's card via either:

  1. Container labels (per-service, lives in compose) — authoritative, requires recreating the container.
  2. overrides.json (one file, lives next to compose) — non-disruptive, no container restart, easy to edit.

Container labels win over the overrides file; the overrides file wins over defaults.

Container labels

Label Effect
dockerview.name Display name (default: container name)
dockerview.description One-line description shown under the name
dockerview.group Group tag (default: compose project)
dockerview.url Override the link target
dockerview.port Pick which published port to link to
dockerview.scheme http / https (auto-guessed for 443/8443)
dockerview.hidden true to hide this container from the list
dockerview.icon Reserved for future use

overrides.json

A single JSON file keyed by raw container name (what docker ps shows). Start from overrides.example.json — copy it to overrides.json and edit. Mounted into the container at /data/overrides.json (read-only). Re-read on every refresh — just save the file and the page picks up the change.

{
  "jellyfin": {
    "name": "Jellyfin",
    "description": "私人媒体中心",
    "group": "媒体",
    "url": "https://jellyfin.your-domain.com"
  },
  "paperless-db-1": { "hidden": true }
}

Fields: name, description, group, url, scheme, port, icon, hidden. All optional.

Example

services:
  jellyfin:
    image: jellyfin/jellyfin
    labels:
      dockerview.name: "Jellyfin"
      dockerview.description: "Media server"
      dockerview.group: "media"

Environment

Var Default What it does
PORT 8787 HTTP port
PUBLIC_HOST localhost Host part of the URLs DockerView renders
DOCKERVIEW_MOCK unset 1 to use the bundled sample data
DOCKER_SOCKET /var/run/docker.sock Path to the Docker socket inside the container

Security

DockerView has no built-in authentication. The /api/services endpoint exposes the full container inventory — image names and tags, published ports, network names, labels, health. Treat it like an internal admin tool:

  • Only bind it to a trusted network (LAN, Tailscale, WireGuard), or
  • Put it behind a reverse proxy with auth (Authelia, Cloudflare Access, oauth2-proxy).

Don't expose port 8787 directly to the public internet.

The Docker socket is mounted read-only and DockerView only issues read-only Docker API calls (/containers/json, /containers/{id}/json, /info, /_ping). It cannot start, stop, or modify containers.

Keyboard

  • ⌘K / Ctrl+K / / — open the search palette
  • ↑ ↓ — move
  • ↩ — open the highlighted service
  • Esc — close

Scripts

  • bun run dev — concurrent Vite + Bun dev server (mock with DOCKERVIEW_MOCK=1)
  • bun run build — build the frontend into dist/web
  • bun run start — production: Bun serves dist/web and the API on the same port
  • bun run typecheck — TS check, no emit

License

MIT

Contributors

xinghelee

Issues