heddohon

heddohon

Docker app from zorcerer's Repository

Overview

A music player for a Navidrome, Subsonic or Jellyfin library, rendered on the server. Audio and artwork are fetched by Heddohon rather than by the browser, so the music server never has to be reachable from the devices you play on: one hostname is exposed and the library stays where it is. Sign-in is a live call to the music server, so there is no second set of accounts to keep. Streams the original file by default, with no transcoding or resampling, and shows what is being decoded. Transcoding to MP3, Opus or AAC is a setting, and the quality badge in the player switches it on and off mid-track for a connection that will not carry the original. Synced lyrics, a tight track handoff, a server-side cover cache, and per-account settings and queue that follow you between devices.

Heddohon

Server-rendered music player for Navidrome/Subsonic and Jellyfin.

Release Build Docker Pulls Docker Image Size License
SvelteKit TypeScript Node

The album view, with the now-playing panel on the right

Heddohon connects to your music server from its own backend, so the browser only talks to Heddohon. Audio and artwork are proxied through it, which makes Heddohon the only host you expose and keeps upstream credentials on the server.

 browser ──► Heddohon ──► Navidrome / Jellyfin

Features

  • Original files by default: audio streams as it sits on disk, and the player shows the decoded format (FLAC 24/192, MP3 320).
  • Optional transcoding: MP3, Opus or AAC at a chosen bitrate, toggled mid-track from the quality badge.
  • Server-side rendering: pages arrive with the theme and interface scale already applied.
  • Per-account state: settings and queue sync across devices.
  • Cached cover art, synced lyrics and recommendations from your music server.
  • Fast track handoff: the next track is pre-buffered so it starts right away. Audio covers the details.
  • Accent colour sampled from the current album cover.
Synced lyrics in the now-playing panel, the current line highlighted An album page with the artist's other records below the track list
Synced lyrics More from the artist and recommendations

Quick start

git clone https://github.com/zorcerer/heddohon.git && cd heddohon
cp .env.example .env
echo "HEDDOHON_SECRET=$(openssl rand -base64 48)" >> .env
echo "HEDDOHON_SUBSONIC_URL=http://10.0.0.10:4533" >> .env
docker compose up -d

Open http://localhost:13000 and sign in with your music server account. To expose it publicly, set ORIGIN and read SECURITY.md.

Images: ghcr.io/zorcerer/heddohon or zorcererd/heddohon. An Unraid template is in templates/heddohon.xml. To run it with Node 22+ instead of Docker: npm ci && npm run build && node build/index.js.

Documentation

AI disclosure

Written with assistance from Claude. The code and security posture have been reviewed by me and by AI-assisted audits, documented in SECURITY.md. A professional third-party audit has yet to be done.

License

MIT

Media gallery

1 / 3

Install Heddohon on Unraid in a few clicks.

Find Heddohon in Community Apps on your Unraid server, review the template, and click Install. Unraid handles the Docker app or plugin setup from the published template.

Open the Apps tab on your Unraid server Search Community Apps for Heddohon Review the template variables and paths Click Install

Related apps

Explore more like this

Explore all

Details

Repository
ghcr.io/zorcerer/heddohon:latest
Last Updated2026-09-17
First Seen2026-09-17

Runtime arguments

Web UI
http://[IP]:[PORT:3000]
Network
bridge
Shell
bash
Privileged
false
Extra Params
--user 99:100

Template configuration

WebUIPorttcp

Port the interface is served on.

Target
3000
Default
13000
Value
13000
AppdataPathrw

Holds the SQLite database and the cover cache.

Target
/data
Default
/mnt/user/appdata/heddohon
Value
/mnt/user/appdata/heddohon
SecretVariable

Encrypts stored music-server credentials and derives session keys. Minimum 32 characters: openssl rand -base64 48. Changing it signs everyone out.

Target
HEDDOHON_SECRET
Navidrome / Subsonic URLVariable

Base URL of your Navidrome or Subsonic server, resolved by this container rather than by the browser. Leave empty if you only use Jellyfin.

Target
HEDDOHON_SUBSONIC_URL
Jellyfin URLVariable

Base URL of your Jellyfin server. Leave empty if you only use Navidrome.

Target
HEDDOHON_JELLYFIN_URL
Public URLVariable

The address you reach Heddohon on, needed behind a reverse proxy for the CSRF origin check. For example https://music.example.com

Target
ORIGIN
Cover cacheVariable

Megabytes of cover art kept under the appdata path. The least recently used files are dropped once it is passed. 0 switches the cache off.

Target
HEDDOHON_COVER_CACHE_MB
Default
512
Value
512
Session hoursVariable

How long a sign-in lasts. Capped at 72 whatever is set here, and never extended by activity.

Target
HEDDOHON_SESSION_HOURS
Default
72
Value
72
Application nameVariable

Shown on the sign-in screen and in the sidebar.

Target
HEDDOHON_APP_NAME
Default
Heddohon
Value
Heddohon
Log levelVariable

error, warn, info or debug. The default writes nothing while the server is working. debug times every call to the music server, for working out why a page is slow.

Target
HEDDOHON_LOG_LEVEL
Default
error
Value
error
Secure cookieVariable

auto marks the session cookie Secure. In this image that is always, whatever the scheme. Set false if you reach this over plain http on the LAN, or sign-in will not stick.

Target
HEDDOHON_COOKIE_SECURE
Default
auto
Value
auto
Navidrome labelVariable

Name shown for this server on the sign-in screen.

Target
HEDDOHON_SUBSONIC_LABEL
Default
Navidrome
Value
Navidrome
Jellyfin labelVariable

Name shown for this server on the sign-in screen.

Target
HEDDOHON_JELLYFIN_LABEL
Default
Jellyfin
Value
Jellyfin
Sign-in hintVariable

An optional line of text on the sign-in screen, for telling users which account to use.

Target
HEDDOHON_LOGIN_HINT
Upstream timeoutVariable

Milliseconds to wait on the music server before giving up.

Target
HEDDOHON_UPSTREAM_TIMEOUT_MS
Default
20000
Value
20000