The server hosts the web app and your media files, and can run on pretty much anything including a Raspberry Pi, NAS or Windows/Mac/Linux desktop. Since the player is fully browser-based, it doesn’t need to run on the same system as the server, but it can.
KaraokeArcade Server is available as both a Docker image and an npm package. Both options are multi-platform and multi-architecture (64-bit required).
Docker is the preferred way to run KaraokeArcade Server if you’re using a dedicated server or NAS. The KaraokeArcade docker image is modeled after LinuxServer’s images and supports both amd64 and arm64.
The easiest way to use the Docker image is via a Compose file, which is a simple YAML format for configuring your container.
Below is an example docker compose file:
services:
karaokearcade:
container_name: karaokearcade
image: radrootllc/karaoke-eternal
volumes:
# Folder where the KaraokeArcade Server database will be created
- <path_to_database>:/config
# Folder(s) containing your media
# (inside the app, you'll add /mnt/karaoke to Media Folders)
- <path_to_media>:/mnt/karaoke
ports:
# Web server port
- <host_port>:8080
# environment:
# - PUID=1000 # optional: user ID to run as
# - PGID=1000 # optional: group ID to run as
# - TZ=America/New_York # optional: timezone
restart: unless-stoppedAt a minimum, replace <path_to_database>, <path_to_media> and <host_port> with the desired values. See the CLI & ENV section for additional environment settings.
Once the container is running, see Getting Started if you’re new to KaraokeArcade.
KaraokeArcade Server is also available as an npm package:
Install Node.js v24 or later if it’s not already installed.
In your terminal or command prompt, run the following:
npm i -g karaokearcadekaraokearcade-serverSee Getting Started if you’re new to KaraokeArcade.
The following file types are supported:
KaraokeArcade Server expects your media files to be named in “Artist - Title” format by default (you can configure this). Media with filenames that couldn’t be parsed won’t appear in the library, so check the scanner log or console output for these.
You can customize the metadata parser by creating a file named _kes.v2.json in a media folder. It will apply to all media files in the folder, including subfolders. If any subfolders contain their own _kes.v2.json file, that will take precedence instead. These files can be in JSON or JSON5 format - JSON5 is used in the examples below since it’s friendlier for humans.
At the most basic, your _kes.v2.json file can alter some or all of the parser’s default configuration, which is:
{
// used to normalize artist/title; set false to disable
articles: ['A', 'An', 'The'],
// assumes filenames are in "Artist - Title" format
artistOnLeft: true,
// assumes a hyphen separates the artist and title
delimiter: '-',
}For example, if you had a folder with filenames in the format “Title - Artist” instead, you could create this _kes.v2.json file in it:
{
artistOnLeft: false, // override default
}If changing the parser’s default configuration doesn’t yield the desired results, you can also define your own “template” to override the result for one or more of these fields:
artist (string) artist’s name as it will be shown in the libraryartistNorm (string) normalized version of the artist’s name; used for matching and sorting (artist if not set)title (string) song’s title as it will be shown in the librarytitleNorm (string) normalized version of the song’s title; used for matching and sorting (title if not set)For each media file encountered, KaraokeArcade makes a “context” available to your field template(s). This context includes the fields above (that is, the results from the built-in parser) in addition to:
name (string) media filename (without extension)meta (object) media file’s metadata fieldsdir (string) full path of the containing folderdirSep (string) path separator used by the current OS (/ or \)Field templates are defined using JSON-e syntax. In addition to JSON-e’s built-in methods, a replace method is also provided for simple text replacement. Here are a few examples of how one might use field templates in their _kes.v2.json file:
// explicitly set the artist field
{
artist: "My Artist's Name",
}// remove "junk" from anywhere in the parsed artist field
{
artist: {
$eval: 'replace(artist, "junk", "")'
},
}// remove "junk" case-insensitively from the start of the parsed artist field (regex syntax)
// note: double backslash escapes to a single backslash
{
artist: {
$eval: 'replace(artist, "^junk\\s", "i", "")'
},
}// set artist and title using the media file's metadata tags
{
artist: '${meta.artist}',
title: '${meta.title}',
}KaraokeArcade Server supports the following CLI options and environment variables. The numeric values used for log/console levels are: 0=off, 1=error, 2=warn, 3=info, 4=verbose, 5=debug
| Option | ENV | Description | Default |
|---|---|---|---|
--data <string> |
KES_PATH_DATA |
Absolute path of folder for database files | |
-p, --port <number> |
KES_PORT |
Web server port | auto |
--rotateKey |
KES_ROTATE_KEY |
Rotate the session key at startup | |
--scan |
KES_SCAN |
Run the media scanner at startup. Accepts a comma-separated list of pathIds, or “all” | |
--scannerConsoleLevel <number> |
KES_SCANNER_CONSOLE_LEVEL |
Media scanner console output level (default=4) | 4 |
--scannerLogLevel <number> |
KES_SCANNER_LOG_LEVEL |
Media scanner log file level | 3 |
--serverConsoleLevel <number> |
KES_SERVER_CONSOLE_LEVEL |
Web server console output level | 4 |
--serverLogLevel <number> |
KES_SERVER_LOG_LEVEL |
Web server log file level | 3 |
--serverUrl <string> |
KES_SERVER_URL |
Absolute http(s) URL guests reach the server at, used for join QR codes. See Stable addresses |
current LAN IP |
--urlPath <string> |
KES_URL_PATH |
Web server base URL path (must begin with a forward slash) | / |
-v, --version |
Show version and exit |
By default the join QR encodes the server’s current LAN IP. That works for a one-off party, but an IP is an address rather than an identity: it changes when you take the server to a different venue, and it can change at the same venue when the DHCP lease renews.
This matters if guests add the app to their home screen. An install freezes whatever URL it was added from, and a standalone window has no address bar to correct it, so a changed IP leaves a dead icon. Worse, private ranges are heavily reused, so the old address may reach some unrelated device on the new network.
Set --serverUrl to a name that follows the server between networks and the QR, the install and the icon all agree:
karaokearcade-server --serverUrl http://karaokearcade.local:8080
A Bonjour .local name is the simplest option, and iOS and macOS resolve it with no setup on the guest’s phone. macOS hosts already answer <computer-name>.local; on Linux this needs Avahi, and on Windows the Bonjour service. A tunnel or reverse proxy hostname works too, and an https one additionally unlocks the browser features that require a secure context.
The value is used verbatim, so include the port and any base path. It is ignored (with a warning, falling back to the LAN IP) unless it parses as an http or https URL — note that karaokearcade.local:8080 is not one, since it has no scheme.
Until a name is set, the app doesn’t suggest adding itself to the home screen at all: guests reaching it at a raw IP are left on the QR-and-browser flow, which keeps working no matter how the address moves.
If using the Docker image, the database will be located in the folder you mapped to the container’s /config folder. The container doesn’t write log files by default; use the Docker logs command instead to see the container’s output.
If using the npm installation method, the default locations for the database (database.sqlite3), web server log (server.log) and media scanner log (scanner.log) are as follows:
These folders keep the pre-rebrand Karaoke Eternal Server name so existing installs keep their database.
%USERPROFILE%\AppData\Roaming\Karaoke Eternal Server%USERPROFILE%\AppData\Roaming\Karaoke Eternal Server\logs~/Library/Application Support/Karaoke Eternal Server~/Library/Logs/Karaoke Eternal Server~/.config/Karaoke Eternal Server~/.config/Karaoke Eternal Server/logs©2026 Matthew Antone · Source on GitHub