How to Install Koel Music Streaming Server using Docker on Rocky Linux 8
On this page
- Prerequisites
- Step 1 - Configure Firewall
- Step 2 - Install Docker
- Step 3 - Install Docker Compose
- Step 4 - Create Koel App Key
- Step 5 - Create Koel Environment File
- Step 6 - Create Koel Docker Compose File
- Step 7 - Start Koel Container
- Step 8 - Install SSL
- Step 9 - Install Nginx
- Step 10 - Access Koel
- Step 11 - Import Music
- Step 12 - Update Koel
- Conclusion
Koel is a web-based audio streaming service written in the Laravel PHP framework. It allows you to stream your personal music collection and access it from anywhere in the world. It supports multiple media formats, including AAC, OGG, WMA, FLAC, and APE.
In this tutorial, you will learn how to install Koel Music Streaming Server using Docker on a Rocky Linux 8 machine.
Prerequisites
-
A Server running Rocky Linux 8.5.
-
A non-root user with sudo privileges.
-
Update everything.
$ sudo dnf update
-
Install essential packages.
$ sudo dnf install yum-utils nano curl
-
A custom domain name pointing to the server like
koel.example.com
.
Step 1 - Configure Firewall
The first step is to configure the firewall. Rocky Linux uses Firewalld Firewall. Check the firewall's status.
$ sudo firewall-cmd --state running
The firewall works with different zones, and the public zone is the default one that we will use. List all the services and ports active on the firewall.
$ sudo firewall-cmd --permanent --list-services
It should show the following output.
cockpit dhcpv6-client ssh
Allow HTTP and HTTPS ports.
$ sudo firewall-cmd --permanent --add-service=http $ sudo firewall-cmd --permanent --add-service=https
Recheck the status of the firewall.
$ sudo firewall-cmd --permanent --list-services
You should see a similar output.
cockpit dhcpv6-client http https ssh
Reload the firewall to enable the changes.
$ sudo firewall-cmd --reload
Step 2 - Install Docker
Rocky Linux ships with an older version of Docker. To install the latest version, first, install the official Docker repository.
$ sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo
Install the latest version of Docker.
$ sudo dnf install docker-ce docker-ce-cli containerd.io
Enable and run the Docker daemon.
$ sudo systemctl enable docker --now
Verify that it is running.
? docker.service - Docker Application Container Engine Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled) Active: active (running) since Sat 2022-04-02 13:26:08 UTC; 2s ago Docs: https://docs.docker.com Main PID: 21152 (dockerd) Tasks: 7 Memory: 30.9M CGroup: /system.slice/docker.service ??21152 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock ...
By default, Docker requires root privileges. If you want to avoid using sudo
every time you run the docker
command, add your username to the docker
group.
$ sudo usermod -aG docker $(whoami)
You will need to log out of the server and back in as the same user to enable this change.
Step 3 - Install Docker Compose
Download the latest stable release of Docker Compose.
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
Apply executable permissions to the Docker Compose binary file.
$ sudo chmod +x /usr/local/bin/docker-compose
Test the installation.
$ docker-compose --version docker-compose version 1.29.2, build 5becea4c
Install the Docker-compose Bash Completion script.
$ sudo curl \ -L https://raw.githubusercontent.com/docker/compose/1.29.2/contrib/completion/bash/docker-compose \ -o /etc/bash_completion.d/docker-compose
Reload your profile settings to make the bash-completion work.
$ source ~/.bashrc
Step 4 - Create Koel App Key
We will generate Koel's App key by running the container for a short moment. Run the following command to run the container and access its shell.
$ docker run -it --rm phanan/koel bash
Once in the container, run the following command to generate the application key.
$ php artisan key:generate --force
Output the modified environment file with the newly generated app key.
$ cat .env APP_KEY=base64:fjtO7aVHHKWfk4DThKqf1nci6o2DuMkNd90TKX6Gj+4=
Copy the key value and exit the container shell.
$ exit
Step 5 - Create Koel Environment File
Create a directory for Koel.
$ mkdir ~/koel
Switch to the directory.
$ cd ~/koel
Create the music directory.
$ mkdir music
Create and open the .env
file.
$ nano .env
Paste the following code in it.
APP_NAME=Koel # A random 32-char string. You can leave this empty if use php artisan koel:init. APP_KEY=base64:fjtO7aVHHKWfk4DThKqf1nci6o2DuMkNd90TKX6Gj+4= # The ABSOLUTE path to your media. This value can always be changed later via the web interface. MEDIA_PATH=/music APP_ENV=production APP_DEBUG=true APP_URL=https://koel.example.com # The maximum scan time, in seconds. Increase this if you have a huge library. # Note: This setting doesn't have effect when scanning via koel:sync. APP_MAX_SCAN_TIME=600 # The memory limit, in MB, used by the scanning process. # For example, if you want to set a memory limit of 2048MB, enter "2048" (without # quotes) here. MEMORY_LIMIT=512 # The streaming method. # Can be either 'php' (default), 'x-sendfile', or 'x-accel-redirect' # See https://docs.koel.dev/#streaming-music for more information. # Note: This setting doesn't have effect if the media needs transcoding (e.g. FLAC). STREAMING_METHOD=x-sendfile # If you want Koel to integrate with Last.fm, set the API details here. # See https://docs.koel.dev/3rd-party.html#last-fm for more information LASTFM_API_KEY= LASTFM_API_SECRET= # If you want to use Amazon S3 with Koel, fill the info here and follow the # installation guide at https://docs.koel.dev/aws-s3.html AWS_ACCESS_KEY_ID= AWS_SECRET_ACCESS_KEY= AWS_REGION= # If you want Koel to integrate with YouTube, set the API key here. # See https://docs.koel.dev/3rd-party.html#youtube for more information. YOUTUBE_API_KEY= # You can also configure Koel to use a CDN to serve the media files. # This url must be mapped to the home URL of your Koel's installation. # No trailing slash, please. CDN_URL= # The bit rate of the output mp3 stream. Higher value results in better quality, # but slower streaming and more bandwidth. OUTPUT_BIT_RATE=128 # Whether to allow song downloading. # Note that if you're downloading more than one song, Koel will zip them up # using PHP's ZipArchive. So if the module isn't available in the current # environment, such a download will (silently) fail. ALLOW_DOWNLOAD=true # If this is set to true, the query to get artist, album, and song information will be cached. # This can give a boost to Koel's boot time, especially if your library is huge. # However, the cache deserialization process can be memory sensitive, so if you encounter # errors, try setting this to false. CACHE_MEDIA=true # Koel attempts to detect if your website use HTTPS and generates secure URLs accordingly. # If this attempts for any reason, you can force it by setting this value to true. FORCE_HTTPS=true # The variables below are Laravel-specific. # You can change them if you know what you're doing. Otherwise, just leave them as-is. APP_LOG_LEVEL=debug BROADCAST_DRIVER=log CACHE_DRIVER=file SESSION_DRIVER=file QUEUE_DRIVER=sync
Save the file by pressing Ctrl + X and entering Y when prompted.
Most of the settings are self-explanatory above. The following settings need to be configured to make it work. Paste the app key generated in the previous step against the APP_KEY
variable. Enter your domain name under APP_URL
, and set the memory limit in MBs depending on your server's resources. We have set the streaming method to x-sendfile
as Koel's docker image uses Apache and comes pre-configured with it. The FORCE_HTTPS
setting is set to true because we will use Nginx as a load balancer along with Let's Encrypt SSL to serve Koel to the web. Configure other services if you want to use them along with Koel.
Step 6 - Create Koel Docker Compose File
Create and open the file docker-compose.yml
for editing.
$ nano docker-compose.yml
Paste the following code into it.
version: '3.3' services: koel: image: phanan/koel container_name: koel depends_on: - koeldb restart: unless-stopped ports: - 8080:80 environment: - DB_CONNECTION=mysql - DB_HOST=koeldb - DB_USERNAME=koel - DB_PASSWORD=koelpassword - DB_DATABASE=koel volumes: - ./music:/music - ./.env:/var/www/html/.env - covers:/var/www/html/public/img/covers - search_index:/var/www/html/storage/search-indexes koeldb: image: mysql/mysql-server:8.0 restart: unless-stopped volumes: - db:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=rootpassword - MYSQL_DATABASE=koel - MYSQL_USER=koel - MYSQL_PASSWORD=koelpassword volumes: db: driver: local covers: driver: local search_index: driver: local
Save the file by pressing Ctrl + X and entering Y when prompted.
The above file launches containers based on Koel and MySQL's docker images. It exposes Koel to port 8080 on your machine. The music and the environment file are mounted to the respective locations on the container. The directory for music covers and the search index, along with MySQL data, is mounted as local volumes. Choose a strong password for the variables MYSQL_ROOT_PASSWORD
, MYSQL_PASSWORD
and match those values with the variables for the Koel container in the file above. To link the Koel container with the database container, make sure the DB_HOST
and depends_on
variables are named after the Database container's service name.
Step 7 - Start Koel Container
Launch the Koel Container using the following command.
$ docker-compose up -d
Initialize Koel for the first time
Log in to the Koel Container shell. koel
in the command below refers to the name of the container set via the container_name
variable in the Docker compose file above. If you don't have a container name set, you will have to find the name of the container first and use that in the following command.
$ docker exec --user www-data -it koel bash
Run the following command to create an administrator account and initialize the database.
$ php artisan koel:init --no-assets
Change Administrator Password
Koel creates a default administrator account with the following credentials.
email: [email protected] password: KoelIsCool
You can change the password for the administrator account using the following command from inside the container shell.
$ php artisan koel:admin:change-password
Exit the container shell.
$ exit
Step 8 - Install SSL
To install an SSL certificate using Let's Encrypt, we need to install the Certbot tool.
Firstly, you need to download and install the EPEL repository.
$ sudo dnf install epel-release
Run the following commands to install Certbot.
$ sudo dnf install certbot
Generate the SSL certificate.
$ sudo certbot certonly --standalone --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m [email protected] -d koel.example.com
The above command will download a certificate to the /etc/letsencrypt/live/koel.example.com
directory on your server.
Generate a Diffie-Hellman group certificate.
$ sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096
Create a challenge web root directory for Let's Encrypt auto-renewal.
$ sudo mkdir -p /var/lib/letsencrypt
Create a Cron Job to renew the SSL. It will run every day to check the certificate and renew it if needed. For that, first, create the file /etc/cron.daily/certbot-renew
and open it for editing.
$ sudo nano /etc/cron.daily/certbot-renew
Paste the following code.
#!/bin/sh certbot renew --cert-name koel.example.com --webroot -w /var/lib/letsencrypt/ --post-hook "systemctl reload nginx"
Save the file by pressing Ctrl + X and entering Y when prompted.
Change the permissions on the task file to make it executable.
$ sudo chmod +x /etc/cron.daily/certbot-renew
Step 9 - Install Nginx
We will be installing the latest version of Nginx. Create and open the file /etc/yum.repos.d/nginx.repo
for editing.
$ sudo nano /etc/yum.repos.d/nginx.repo
Paste the following lines in it.
[nginx-stable] name=nginx stable repo baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck=1 enabled=1 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true [nginx-mainline] name=nginx mainline repo baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/ gpgcheck=1 enabled=0 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true
Save the file by pressing Ctrl + X and entering Y when prompted.
Install Nginx.
$ sudo dnf install nginx
Verify the installation.
$ nginx -v nginx version: nginx/1.20.2
Enable and start the Nginx service.
$ sudo systemctl enable nginx --now
Create and open the file /etc/nginx/conf.d/koel.conf
for editing.
$ sudo nano /etc/nginx/conf.d/koel.conf
Paste the following code in it.
# Redirect all non-encrypted to encrypted server { listen 80; listen [::]:80; server_name koel.example.com; return 301 https://$host$request_uri; } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name koel.example.com; ssl_certificate /etc/letsencrypt/live/koel.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/koel.example.com/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/koel.example.com/chain.pem; ssl_session_timeout 1d; ssl_session_cache shared:MozSSL:10m; ssl_session_tickets off; ssl_stapling on; ssl_stapling_verify on; ssl_dhparam /etc/ssl/certs/dhparam.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; access_log /var/log/nginx/koel.example.com.access.log main; error_log /var/log/nginx/koel.example.com.error.log; location / { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Port $server_port; proxy_set_header X-Forwarded-Host $host; client_max_body_size 400M; proxy_pass http://localhost:8080; proxy_http_version 1.1; proxy_set_header Host $host; } }
Once finished, save the file by pressing Ctrl + X and entering Y when prompted. The above configuration allows Nginx to act as a proxy server and bind to the port 8080 on localhost.
Open the file /etc/nginx/nginx.conf
for editing.
$ sudo nano /etc/nginx/nginx.conf
Add the following line before the line include /etc/nginx/conf.d/*.conf;
.
server_names_hash_bucket_size 64;
Save the file by pressing Ctrl + X and entering Y when prompted.
Verify the Nginx configuration file syntax.
$ sudo nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
Restart the Nginx service to enable the new configuration.
$ sudo systemctl restart nginx
Step 10 - Access Koel
You can access Koel by visiting the URL https://koel.example.com
in your browser. You will be greeted by the following login screen.
Enter [email protected]
as your username and the password you set before logging in. The following dashboard will appear on successful login.
Step 11 - Import Music
Copy the music files you want to import to the ~/koel/music
folder of your system. You can use the scp
command to import the files from your local PC to the server.
$ scp test.mp3 user@<yourserverIP>:/home/user/koel/music
Once you have copied the files to the ~/koel/music
folder, run the following command to import the music into Koel.
$ docker exec --user www-data koel php artisan koel:sync
The music will show up in Koel's web interface, and you can start playing.
Koel's web interface also allows you to upload songs directly.
Step 12 - Update Koel
Switch to the Koel directory.
$ cd ~/koel
Pull the latest Koel Docker image.
$ docker-compose pull
Power down the container.
$ docker-compose down --remove-orphans
Start the container with updated images.
$ docker-compose up -d
Verify the Docker containers.
$ docker ps
Conclusion
This concludes the tutorial on installing Koel Music Streaming Service using Docker on a Rocky Linux server. If you have any questions, post them in the comments below.