LunaSea is a browser-based PWA for managing self-hosted media services.
This build is web-only. It supports Lidarr, Radarr, Sonarr, NZBGet, SABnzbd, Newznab-compatible search, NZBHydra2, Tautulli, and external links.
LunaSea Web does not include authentication or access control. Anyone who can reach the app can use the configured service connections.
Run it only on trusted networks, or place it behind a protected reverse proxy, Tailscale, Cloudflare Access, Authelia, Authentik, or another access-control layer. Do not expose it directly to the public internet.
Start LunaSea with Docker Compose:
docker compose upOpen http://localhost:8080.
By default, the app is only exposed on localhost.
To build and run the image from this checkout:
docker compose -f compose.example.yaml up --buildTo build and run the image without Compose:
docker buildx build --load --tag lunasea-web:local .
docker run --rm \
-p 127.0.0.1:8080:8080 \
-v lunasea-data:/data \
lunasea-web:localOpen Settings in the app and add each service.
Service URLs, credentials, profiles, preferences, indexers, external modules, dismissed banners, and logs are stored in the server-side SQLite database. Service traffic is proxied through the same origin as the app, which avoids browser CORS, mixed-content, and private-network restrictions.
Application state is stored in /data/lunasea.db. Keep /data on a persistent volume if you want configuration to survive container replacement.
The browser does not own persistent LunaSea configuration. Reloading the page or clearing browser site data does not clear the app configuration. Removing the /data volume resets LunaSea Web to its default backend state.
