Zum Hauptinhalt springen
S-EDV news
← Alle Anleitungen
📘 Anleitung Cloud / Hosting 05.07.2026 · 8 min Lesezeit

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

Symbolbild zur Anleitung: Koel mit Docker installieren

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

  1. Docker Engine und Docker Compose v2, siehe Docker und Docker Compose auf Linux installieren
  2. Linux-Host, VM oder NAS mit amd64, arm64 oder arm/v7 (auch Raspberry Pi)
  3. Mindestens 1 GB RAM, bei großen Bibliotheken 2 GB; rund 10 GB freier Speicher für Images, Datenbank und Suchindex
  4. Musiksammlung als MP3, FLAC, AAC, OGG oder ähnliche Formate auf dem Host
  5. 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
EigenschaftWert
Imagephanan/koel:9.15.0 (Docker Hub, Stand September 2026)
Architekturenlinux/amd64, linux/arm64, linux/arm/v7
Image-Größerund 410 MB (amd64)
Port im Container80 (HTTP)
DatenbankMariaDB 10.11 (wie im offiziellen Compose-Beispiel) oder PostgreSQL
LizenzMIT
VolumeZweck
/pfad/zur/musik:/music:roIhre Musikdateien, nur lesend
./koel.env:/var/www/html/.envKoel-Konfiguration mit APP_KEY
koel_imagesAlbum-Cover und Avatare
koel_searchSuchindex
koel_dbMariaDB-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=false

Das 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.env

Verifizieren: 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 koel

Beim 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_PORT

grep 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-password

Der 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:scan

koel: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>&1

Verifizieren: 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=true
docker compose up -d

Verifizieren: 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 -d

Beim Start führt Koel ausstehende Datenbankmigrationen automatisch aus, solange SKIP_INIT nicht gesetzt ist. Erstellen Sie vorher ein Backup:

  1. .env und koel.env (Passwörter und APP_KEY, verschlüsselt aufbewahren)
  2. Datenbank-Dump: docker exec koel_db sh -c 'mariadb-dump -u koel -p"$MARIADB_PASSWORD" koel' > koel_backup.sql
  3. 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

  1. Log meldet „No .env file found in /var/www/html“, Anmeldung scheitert: koel.env ist nicht eingebunden oder fehlt, deshalb lief koel:init nicht. Legen Sie die Datei wie in Schritt 2 an und starten Sie mit docker compose up -d neu.
  2. Permission denied beim Schreiben der .env: koel.env gehört nicht UID 33. Beheben mit sudo chown 33:33 /opt/koel/koel.env.
  3. SQLSTATE[HY000] [2002] Connection refused: Koel startete vor der Datenbank. Prüfen Sie depends_on mit condition: service_healthy und starten Sie mit docker compose restart koel neu.
  4. address already in use: Der Port ist belegt. Setzen Sie KOEL_PORT in der .env auf einen freien Wert.
  5. 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.
  6. Mixed-Content-Fehler hinter HTTPS-Proxy: FORCE_HTTPS=true oder die HTTPS-APP_URL fehlt in der .env.
  7. Nach Neustart abgemeldet oder Fehler „The MAC is invalid“: Der APP_KEY hat sich geändert, meist weil koel.env ersetzt wurde. Spielen Sie die gesicherte koel.env zurück.
  8. Hohe CPU-Last beim ersten Scan: Bei großen Bibliotheken normal. Scannen Sie mit --jobs=1 oder --jobs=2 zu 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

  1. Caddy als Reverse Proxy mit automatischem HTTPS einrichten
  2. Docker Compose absichern: Secrets, Healthchecks und Non-Root
  3. 3-2-1-Backup-Strategie umsetzen: Anleitung mit Restic, USB-Disk und S3-Cloud
  4. 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.

Passende Anleitungen auf S-EDV

  1. netcup Local Block Storage bestellen, einrichten und unter Linux einbinden