Koel mit Docker installieren: Schlanker persönlicher Musik-Streamingserver
Koel mit Docker Compose und MariaDB einrichten: fester Image-Tag, dauerhafter APP_KEY über eingebundene .env, gebundener Port, Standard-Passwort ändern, Bibliothek scannen, HTTPS per Reverse Proxy und Backup.
Geprüft am 30.09.2026 · für phanan/koel 9.15.0
WerbelinksMit * markierte Links sind Werbelinks: Bei einem Kauf erhalten wir eine Provision, der Preis bleibt gleich. Als Amazon-Partner verdiene ich an qualifizierten Verkäufen. Mehr dazu

Koel ist ein selbst gehosteter Musik-Streamingserver mit Weboberfläche. Ihre MP3- und FLAC-Dateien bleiben auf eigener Hardware, abgespielt wird im Browser oder in der Mobil-App. Koel basiert auf Laravel und Vue.js, bietet Smart Playlists, Last.fm-Scrobbling und Podcasts und steht unter MIT-Lizenz. Diese Anleitung richtet Koel mit Docker Compose und MariaDB auf einem Linux-Host, einer VM oder einem NAS ein.
Voraussetzungen
- Docker Engine und Docker Compose v2, siehe Docker und Docker Compose auf Linux installieren
- Linux-Host, VM oder NAS mit amd64, arm64 oder arm/v7 (auch Raspberry Pi)
- Mindestens 1 GB RAM, bei großen Bibliotheken 2 GB; rund 10 GB freier Speicher für Images, Datenbank und Suchindex
- Musiksammlung als MP3, FLAC, AAC, OGG oder ähnliche Formate auf dem Host
- Für den Zugriff aus dem Internet: Domain und Reverse Proxy (Caddy, Traefik oder Nginx); Koel selbst liefert kein TLS
Schritt 1: Projektordner anlegen und Eckdaten überblicken
sudo mkdir -p /opt/koel
cd /opt/koel| Eigenschaft | Wert |
|---|---|
| Image | phanan/koel:9.15.0 (Docker Hub, Stand September 2026) |
| Architekturen | linux/amd64, linux/arm64, linux/arm/v7 |
| Image-Größe | rund 410 MB (amd64) |
| Port im Container | 80 (HTTP) |
| Datenbank | MariaDB 10.11 (wie im offiziellen Compose-Beispiel) oder PostgreSQL |
| Lizenz | MIT |
| Volume | Zweck |
|---|---|
/pfad/zur/musik:/music:ro | Ihre Musikdateien, nur lesend |
./koel.env:/var/www/html/.env | Koel-Konfiguration mit APP_KEY |
koel_images | Album-Cover und Avatare |
koel_search | Suchindex |
koel_db | MariaDB-Daten |
Verifizieren: ls -la /opt/koel zeigt ein leeres Verzeichnis.
Schritt 2: Konfigurationsdateien mit Secrets anlegen
Die Datei .env liest Docker Compose für die Platzhalter in der compose.yaml. Erzeugen Sie zwei zufällige Passwörter, etwa mit openssl rand -base64 24, und legen Sie an:
# /opt/koel/.env
DB_PASSWORD=ZUFAELLIGES_PASSWORT_1
DB_ROOT_PASSWORD=ZUFAELLIGES_PASSWORT_2
# Adresse des Hosts, an die der Port gebunden wird:
# 127.0.0.1 = nur Reverse Proxy auf diesem Host, sonst LAN-IP, z. B. 192.168.1.100
KOEL_BIND=127.0.0.1
KOEL_PORT=8080
APP_URL=http://127.0.0.1:8080
FORCE_HTTPS=falseDas Koel-Image startet die Ersteinrichtung (koel:init: Datenbankmigration, APP_KEY, Admin-Konto) nur, wenn im Container eine Datei /var/www/html/.env existiert. Legen Sie dafür eine leere, für den Container-Benutzer www-data (UID 33) schreibbare Datei an. Koel speichert dort den erzeugten APP_KEY dauerhaft.
touch /opt/koel/koel.env
sudo chown 33:33 /opt/koel/koel.env
sudo chmod 600 /opt/koel/.env /opt/koel/koel.envVerifizieren: ls -la /opt/koel zeigt .env mit -rw------- und Besitzer root sowie koel.env mit -rw------- und Besitzer 33 bzw. www-data.
Schritt 3: compose.yaml erstellen
Der Healthcheck sorgt dafür, dass Koel erst startet, wenn MariaDB bereit ist. Ersetzen Sie /pfad/zur/musik durch den Pfad Ihrer Sammlung.
# /opt/koel/compose.yaml
services:
koel:
image: phanan/koel:9.15.0
container_name: koel
restart: unless-stopped
depends_on:
database:
condition: service_healthy
ports:
- "${KOEL_BIND:-127.0.0.1}:${KOEL_PORT:-8080}:80"
environment:
- DB_CONNECTION=mysql
- DB_HOST=database
- DB_PORT=3306
- DB_USERNAME=koel
- DB_PASSWORD=${DB_PASSWORD}
- DB_DATABASE=koel
- APP_URL=${APP_URL}
- FORCE_HTTPS=${FORCE_HTTPS:-false}
- MEMORY_LIMIT=512
# Optional: Last.fm
# - LASTFM_API_KEY=${LASTFM_API_KEY}
# - LASTFM_API_SECRET=${LASTFM_API_SECRET}
volumes:
- /pfad/zur/musik:/music:ro
- ./koel.env:/var/www/html/.env
- koel_images:/var/www/html/storage/app/public/images
- koel_search:/var/www/html/storage/search-indexes
database:
image: mariadb:10.11
container_name: koel_db
restart: unless-stopped
environment:
- MARIADB_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
- MARIADB_DATABASE=koel
- MARIADB_USER=koel
- MARIADB_PASSWORD=${DB_PASSWORD}
volumes:
- koel_db:/var/lib/mysql
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 10s
timeout: 5s
retries: 10
start_period: 30s
volumes:
koel_db:
koel_images:
koel_search:Die Datenbank hat keinen veröffentlichten Port und ist nur im Compose-Netz erreichbar. Lassen Sie :ro am Musik-Volume weg, wenn Sie über die Weboberfläche Dateien hochladen möchten.
Verifizieren: docker compose config gibt die Konfiguration ohne Fehler aus; unter ports steht Ihre KOEL_BIND-Adresse.
Schritt 4: Stack starten und APP_KEY prüfen
docker compose up -d
docker compose logs -f koelBeim ersten Start lädt Docker die Images, MariaDB initialisiert sich und Koel führt koel:init aus: Datenbankmigrationen, APP_KEY, Standard-Admin. Warten Sie auf die Apache-Meldung resuming normal operations und beenden Sie die Anzeige mit Strg+C.
Der APP_KEY verschlüsselt Sitzungen und gespeicherte Geheimnisse. Er steht jetzt in koel.env und bleibt bei Updates und neu erstellten Containern erhalten. Sichern Sie koel.env zusammen mit der Datenbank; ohne den Schlüssel lassen sich verschlüsselte Daten nicht mehr lesen.
Verifizieren:
sudo grep "^APP_KEY=base64:" /opt/koel/koel.env
docker compose ps
curl -I http://127.0.0.1:8080 # bzw. http://KOEL_BIND:KOEL_PORTgrep findet eine Zeile mit APP_KEY=base64:. docker compose ps zeigt koel_db als (healthy) und koel als Up, die Portspalte beginnt mit Ihrer KOEL_BIND-Adresse. curl liefert 200 oder 302.
Schritt 5: Standard-Passwort sofort ändern
koel:init legt ein Admin-Konto mit öffentlich bekannten Zugangsdaten an: admin@koel.dev / KoelIsCool. Ändern Sie das Passwort, bevor Sie den Dienst im Netz erreichbar machen:
docker exec -it koel php artisan koel:admin:change-passwordDer Befehl fragt nach dem neuen Passwort. Die E-Mail-Adresse ändern Sie nach der Anmeldung im Profil der Weboberfläche.
Verifizieren: Die Anmeldung mit KoelIsCool schlägt fehl, mit dem neuen Passwort gelingt sie. Das Dashboard ist noch leer, weil die Bibliothek nicht gescannt ist.
Schritt 6: Musikbibliothek scannen
Starten Sie den ersten Scan als Benutzer www-data, damit Suchindex und Cover die richtigen Besitzrechte erhalten:
docker exec --user www-data koel php artisan koel:scankoel:sync ist ein gleichwertiger älterer Name. Bei großen Bibliotheken dauert der erste Scan mehrere Minuten; --jobs=2 begrenzt die parallelen Prozesse und damit die Last, MEMORY_LIMIT erhöht bei Bedarf den Speicher des Scanvorgangs.
Neue Dateien erfasst Koel erst beim nächsten Scan. Richten Sie dafür einen Cron-Job auf dem Host ein:
# sudo crontab -e
0 * * * * docker exec --user www-data koel php artisan koel:scan >> /var/log/koel-scan.log 2>&1Verifizieren: Die Scan-Ausgabe meldet die Anzahl gefundener Titel ohne Fehler; Songs, Alben und Künstler erscheinen in der Oberfläche. sudo crontab -l zeigt den Eintrag.
Schritt 7: HTTPS über Reverse Proxy einrichten
Für den Zugriff über das Internet brauchen Sie einen Reverse Proxy mit TLS, siehe Caddy als Reverse Proxy mit automatischem HTTPS einrichten. Läuft der Proxy auf demselben Host, lassen Sie KOEL_BIND=127.0.0.1 stehen und leiten den Proxy auf 127.0.0.1:8080. Passen Sie in der .env an:
APP_URL=https://musik.ihre-domain.de
FORCE_HTTPS=truedocker compose up -dVerifizieren: curl -I https://musik.ihre-domain.de liefert Status 200 oder 302, die Browser-Konsole (F12) zeigt keine Mixed-Content-Warnungen.
Schritt 8: Updates und Backup
Tragen Sie für ein Update den neuen Tag aus den Koel-Releases in der compose.yaml ein und führen Sie aus:
cd /opt/koel
docker compose pull
docker compose up -dBeim Start führt Koel ausstehende Datenbankmigrationen automatisch aus, solange SKIP_INIT nicht gesetzt ist. Erstellen Sie vorher ein Backup:
.envundkoel.env(Passwörter undAPP_KEY, verschlüsselt aufbewahren)- Datenbank-Dump:
docker exec koel_db sh -c 'mariadb-dump -u koel -p"$MARIADB_PASSWORD" koel' > koel_backup.sql - Volume mit Covern:
docker run --rm -v koel_koel_images:/data:ro -v "$(pwd)":/backup alpine tar czf /backup/koel_images.tar.gz -C /data .
Die Musikdateien sichern Sie im Rahmen Ihrer normalen Datensicherung, siehe 3-2-1-Backup-Strategie umsetzen.
Verifizieren: docker compose images zeigt den neuen Tag, koel_db ist (healthy), die Anmeldung funktioniert und koel_backup.sql ist nicht leer.
Troubleshooting / Typische Fehler
- Log meldet „No .env file found in /var/www/html“, Anmeldung scheitert:
koel.envist nicht eingebunden oder fehlt, deshalb liefkoel:initnicht. Legen Sie die Datei wie in Schritt 2 an und starten Sie mitdocker compose up -dneu. Permission deniedbeim Schreiben der .env:koel.envgehört nicht UID 33. Beheben mitsudo chown 33:33 /opt/koel/koel.env.SQLSTATE[HY000] [2002] Connection refused: Koel startete vor der Datenbank. Prüfen Siedepends_onmitcondition: service_healthyund starten Sie mitdocker compose restart koelneu.address already in use: Der Port ist belegt. Setzen SieKOEL_PORTin der.envauf einen freien Wert.- Musik nach dem Scan nicht sichtbar: Das Musikverzeichnis ist für UID 33 nicht lesbar. Geben Sie Leserechte, etwa mit
chmod -R o+rX /pfad/zur/musik, und scannen Sie erneut. - Mixed-Content-Fehler hinter HTTPS-Proxy:
FORCE_HTTPS=trueoder die HTTPS-APP_URLfehlt in der.env. - Nach Neustart abgemeldet oder Fehler „The MAC is invalid“: Der
APP_KEYhat sich geändert, meist weilkoel.enversetzt wurde. Spielen Sie die gesichertekoel.envzurück. - Hohe CPU-Last beim ersten Scan: Bei großen Bibliotheken normal. Scannen Sie mit
--jobs=1oder--jobs=2zu ruhigen Zeiten.
Häufige Fragen
Welche Audioformate unterstützt Koel?
Gängige Formate wie MP3, FLAC, AAC, OGG und WAV. FLAC wird standardmäßig unverändert gestreamt. Mit TRANSCODE_FLAC=true wandelt Koel FLAC per ffmpeg (im Image enthalten) während der Wiedergabe um; die Bitrate legt TRANSCODE_BIT_RATE fest (Standard 128).
Funktioniert Koel auf einem Raspberry Pi?
Ja. Das Image gibt es für linux/arm64 und linux/arm/v7. Ein Raspberry Pi 4 oder 5 mit 4 GB RAM genügt; auf Geräten mit 1 GB RAM scannen Sie mit --jobs=1.
Was ist der Unterschied zwischen Community Edition und Koel Plus?
Die Community Edition steht unter MIT-Lizenz und enthält die Kernfunktionen dieser Anleitung. Koel Plus ist eine kostenpflichtige Erweiterung mit zusätzlichen Funktionen etwa für mehrere Benutzer und Anmeldung über externe Identitätsanbieter; den aktuellen Umfang nennt koel.dev.
Wie richte ich Last.fm-Scrobbling ein?
Legen Sie unter last.fm/api/account/create einen API-Zugang an, tragen Sie LASTFM_API_KEY und LASTFM_API_SECRET in die .env ein, entfernen Sie die Kommentarzeichen in der compose.yaml und starten Sie mit docker compose up -d neu. Ihr Last.fm-Konto verbinden Sie danach im Profil der Weboberfläche.
Wie aktualisiere ich die Bibliothek automatisch bei neuen Dateien?
Mit dem Cron-Job aus Schritt 6. Für sofortige Übernahme kann ein Skript mit inotifywait das Musikverzeichnis beobachten und den Scan nur bei Änderungen starten.
Kann ich statt MariaDB PostgreSQL verwenden?
Ja. Ersetzen Sie den Dienst database durch ein festgelegtes PostgreSQL-Image, setzen Sie DB_CONNECTION=pgsql und DB_PORT=5432 und verwenden Sie POSTGRES_DB, POSTGRES_USER und POSTGRES_PASSWORD. Ein Beispiel liefert docker-compose.postgres.yml im Repository koel/docker.
Fazit
Koel stellt Ihre Musiksammlung mit einer übersichtlichen Weboberfläche bereit, ohne Daten an einen Streamingdienst zu geben. Entscheidend für einen stabilen Betrieb sind vier Punkte: koel.env einbinden, damit Ersteinrichtung und APP_KEY dauerhaft funktionieren; das Standard-Passwort sofort ändern; den Port nur an eine bestimmte Adresse binden und HTTPS über einen Reverse Proxy bereitstellen; Datenbank und koel.env regelmäßig sichern. Weitere Härtungsmaßnahmen beschreibt Docker Compose absichern: Secrets, Healthchecks und Non-Root.
Weiterführende Anleitungen und Quellen
- Caddy als Reverse Proxy mit automatischem HTTPS einrichten
- Docker Compose absichern: Secrets, Healthchecks und Non-Root
- 3-2-1-Backup-Strategie umsetzen: Anleitung mit Restic, USB-Disk und S3-Cloud
- Jellyfin mit Docker: eigener Media-Server ohne Abo
Offizielle Quellen: Koel Docker Repository (koel/docker) mit Compose-Beispielen für MariaDB/MySQL und PostgreSQL. Die allgemeine Koel-Dokumentation unter docs.koel.dev verweist für Docker-Details auf dieses Repository.


