A docker image with only the bare essentials needed to run koel. It includes apache and a php runtime with required extensions.
/!\ This container does not include a database. It requires another container to handle the database.
Since Koel supports many databases you are free to choose any Docker image that hosts one of those databases.
docker-koel (this image) has only been tested with MySQL, so we'll use MySQL in examples below.
docker-compose is the easiest way to get started. It will start both the database container and this image.
Clone this repository and edit docker-compose.yml
. Make sure to replace passwords !
Check out the ./docker-compose.yml
file for more details.
Then run docker-compose:
docker-compose up -d
On the first run, you will need to:
- Generate
JWT_SECRET
andAPP_KEY
- Create an admin user
- Initialize the database
All these steps are achieved by running koel:init
once:
Replace <container_name_for_koel>
in the command by the actual container name.
docker exec -it <container_name_for_koel> bash
# Once inside the container, you can run commands:
$ php artisan koel:init
/!\ koel:init
will fail at the stage where it checks front-end assets. This is known and is due to the absence of node.js and yarn. koel's frontend assets are already built in this image so this step is not necessary.
Create a docker network. It will be shared by Koel and its database.
docker network create --attachable koel-net
Create a database container. Here we will use mysql.
docker run -d --name database \
-e MYSQL_ROOT_PASSWORD=<root_password> \
-e MYSQL_DATABASE=koel \
-e MYSQL_USER=koel \
-e MYSQL_PASSWORD=<koel_password> \
--network=koel-net \
-v koel_db:/var/lib/mysql \
mysql/mysql-server:5.7
Create the koel container on the same network so they can communicate
docker run -d --name koel \
-p 80:80 \
-e DB_CONNECTION=mysql \
-e DB_HOST=database \
-e DB_DATABASE=koel \
-e DB_USERNAME=koel \
-e DB_PASSWORD=<koel_password> \
--network=koel-net \
-v music:/music \
-v covers:/var/www/html/public/img/covers \
hyzual/koel
The same applies for the first run. See the First run section.
To be sure to preserve APP_KEY
and JWT_SECRET
, you can choose to bind-mount the .env
file to your host:
# On your host, create an `.env` file:
touch .env
# Then, you can bind-mount it directly in the container.
docker run -d --name koel \
-p 80:80 \
--mount type=bind,source="$(pwd)"/.env,target=/var/www/html/.env \
hyzual/koel
docker exec -it koel bash
# In the container, init
$ php artisan koel:init
Once you have generated an APP_KEY
and JWT_SECRET
, you can provide them as environment variables to your container to preserve them.
# Run a container just to generate the key
docker run -it --rm hyzual/koel bash
# In the container, generate APP_KEY and JWT_SECRET
$ php artisan key:generate --force
$ php artisan koel:generate-jwt-secret
# Show the modified .env file
$ cat .env
# Copy the APP_KEY and JWT_SECRET variables
$ exit
You can then provide the variables to your real container:
docker run -d --name koel \
-p 80:80 \
-e APP_KEY=<your_app_key> \
-e JWT_SECRET=<your_secret> \
hyzual/koel
# Even better, write an env-file in your host and pass it to the container
docker run -d --name koel \
-p 80:80 \
--env-file .koel.env \
hyzual/koel
Whenever the music in /music
changes, you will need to manually scan it before
koel is able to play it. Run the following command:
docker exec koel php artisan koel:sync
See .env.example
for reference.
DB_CONNECTION
:mysql
ORpgsql
ORsqlsrv
ORsqlite-persistent
. Corresponds to the type of database being used with Koel.DB_HOST
:database
. The name of the Docker container hosting the database. Koel needs to be on the same Docker network to find the database by its name.DB_USERNAME
:koel
. If you change it, also change it in the database container.DB_PASSWORD
: The password credential matchingDB_USERNAME
. If you change it, also change it in the database.DB_DATABASE
:koel
. The database name for Koel. If you change it, also change it in the database.APP_KEY
: a base64 string. It is generated byphp artisan koel:init
or byphp artisan key:generate
. Once you have scanned music, DO NOT CHANGEAPP_KEY
. Songs are identified by a combination ofAPP_KEY
and their path, so ifAPP_KEY
changes, the nextphp artisan koel:scan
will report all songs as changed.JWT_SECRET
: a random 32-char string. It is generated byphp artisan koel:init
or byphp artisan koel:generate-jwt-secret
. DO NOT CHANGEJWT_SECRET
once it is set. You will need it to login.FORCE_HTTPS
: if set totrue
, all URLs redirects done by koel will usehttps
. If you have setup a reverse-proxy in front of this container that supportshttps
, set it totrue
.MEMORY_LIMIT
: amount of memory in MB for the scanning process. Set this ifphp artisan koel:scan
runs out of memory.LASTFM_API_KEY
andLASTFM_API_SECRET
: Enable scrobbling to Last.fm. See https://koel.phanan.net/docs/#/3rd-party?id=last-fm
/music
will contain the music library. Keep in mind that koel needs to
scan music before it's able to play it.
Only HTTP is provided. Consider setting up a reverse-proxy to provide HTTPS support.
Apache's root directory. All koel files will be here. If you exec
into the container, this will be your current directory.