koel 9.15.0 Docker Compose 部署指南

Koel 9.15.0 Docker Compose 部署实战:phanan/koel + MariaDB 10.11 双服务编排、.env 准备与权限排障、数据持久化、等价 docker run 与升级备份,全部步骤实测。

koelkoelDockerDocker Compose自托管2026/10/29

koel 9.15.0 Docker Compose 部署指南

目标:用 Docker Compose 从零部署一套 Koel 9.15.0 音乐流媒体服务(应用 + MariaDB 双服务编排),含初始化、管理员创建、验证、持久化与排障实录。全部命令与回显均在 Ubuntu 24.04.5 LTS 服务器上实测通过。

一、环境信息

本文实测部署所用环境与版本如下:

项目值备注
操作系统Ubuntu 24.04.5 LTS(x86_64)实测服务器
Docker29.9.2docker --version 实测
Docker Composev5.6.1(compose 插件)docker compose version 实测
Koel 镜像phanan/koel:9.15.0官方镜像,digest sha256:af1ec7daf06d22f6...
数据库镜像mariadb:10.11实际运行版本 10.11.19-MariaDB
对外端口8143 → 容器 80实测映射,可按需修改宿主侧端口
部署根目录/opt/koel存放 compose.yml、.env 与音乐目录
演示管理账号admin@koel.dev / q1w2e3r4初始化向导中创建(见步骤 4)

💡 说明:phanan/koel 是 Koel 官方维护的 Docker 镜像(项目源码仓库已迁移为 koel/koel,但镜像名未变,docs.koel.dev 的安装文档仍以 phanan/koel 为准)。

二、镜像选型说明

Koel 的容器化部署只有一个合理起点:官方镜像 phanan/koel,由官方仓库 koel/docker 构建发布。选型要点:

侯选结论依据
phanan/koel(官方)✅ 采用官方构建;内置 Apache 2.4 + PHP 8.4 运行时;自带初始化入口脚本与健康检查
自行从源码构建❌ 无必要官方镜像已含前端编译产物,自建徒增维护成本

官方镜像实测关键行为(本文步骤会逐一用到):

  1. 入口脚本 koel-entrypoint:以 www-data 用户运行 koel-init,后者在检测到 .env 后自动执行 php artisan koel:init --no-assets --no-interaction——即数据库迁移与初始化在每次容器启动时自动完成,无需手动进容器跑安装命令;
  2. 健康检查:镜像内置 curl -f http://localhost/sw.js,每 300 秒一次(docker inspect 实测),docker compose ps 会显示 (healthy);
  3. 内置环境变量:镜像自带 STREAMING_METHOD=x-sendfile(实测 docker inspect 可见),它优先于 .env 文件中的同名变量——这是最常见的"配置不生效"来源,见第七、八章。

数据库镜像选 MariaDB 10.11:官方 Compose 示例同款,LTS 稳定;Koel 也支持 MySQL 8+、PostgreSQL、SQL Server 与 SQLite(.env 的 DB_CONNECTION 值域),个人自用选 MariaDB 或 SQLite 均可,本文与官方示例保持一致用 MariaDB。

三、前置条件

  1. 服务器已安装 Docker 与 Compose 插件(验证命令与实测回显):
docker --version && docker compose version

实测回显:

Docker version 29.9.2, build a82e528
Docker Compose version v5.6.1
  1. 服务器 8143 端口未被占用(如被占用换宿主侧端口即可):
ss -ltnp | grep 8143 || echo "port 8143 free"

实测回显:

port 8143 free
  1. 音乐文件若干(MP3/FLAC 等)。建议按 艺人/专辑/曲名.扩展名 组织,Koel 扫描时按 ID3 标签入 underneath 库:
/opt/koel/music/
├── Echo Lab/
│   └── Signal Path/
│       ├── Pulse One.mp3
│       ├── Midnight Test.mp3
│       └── Dusk Test.mp3
└── Koel Test Band/
    └── Sine Waves/
        ├── Morning Test.mp3
        └── Evening Test.mp3
  1. 目录规划:本文使用 /opt/koel/ 作为部署根目录,其下放置 compose.yml、.env、music/(媒体库)、sql/(可选的数据库首初始化 SQL)。

四、部署步骤

4.1 创建目录与 .env

mkdir -p /opt/koel/music /opt/koel/sql

创建 /opt/koel/.env(Koel 的核心配置文件,完整内容如下,可直接使用;逐项解释见第七章):

APP_NAME=Koel
APP_ENV=production
APP_DEBUG=false
APP_URL=http://127.0.0.1
DB_CONNECTION=mysql
DB_HOST=database
DB_PORT=3306
DB_DATABASE=koel
DB_USERNAME=koel
DB_PASSWORD=koeldb2026
STORAGE_DRIVER=local
MEDIA_PATH=/music
ARTIFACTS_PATH=
IGNORE_DOT_FILES=true
APP_MAX_SCAN_TIME=600
MEMORY_LIMIT=1024
STREAMING_METHOD=php
SCOUT_DRIVER=tntsearch
USE_MUSICBRAINZ=true
TRANSCODE_FLAC=false
ALLOW_DOWNLOAD=true
BACKUP_ON_DELETE=true
PODCASTS_ENABLED=true
RADIO_ENABLED=true
CLEAN_URLS_ENABLED=false
EMBED_ENABLED=true
MAIL_MAILER=log
BROADCAST_CONNECTION=log
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120

⚠️ 注意:APP_KEY 此处留空即可——首次启动时初始化向导会自动生成并写回 .env,前提是该文件对容器内 www-data 用户可写(见 4.3 与第十一章排障实录)。若想手动预生成,可执行 docker run --rm phanan/koel:9.15.0 php artisan key:generate --show,实测输出形如 base64:nBd9gJqcGLKncGcwEH7jcB+QMVXGEk7+ky7kv864rIA=,粘贴到 APP_KEY= 后。

把音乐文件放入 /opt/koel/music/ 后,设置属主与权限(Koel 容器内进程以 www-data 运行,uid 为 33,需要能读媒体、写 .env):

chown -R 33:33 /opt/koel/.env /opt/koel/music
chmod 644 /opt/koel/.env && chmod -R u+rwX /opt/koel/music

4.2 编写 compose.yml

创建 /opt/koel/compose.yml(本文件为实测使用的完整内容):

name: koel-stack

services:
  koel:
    image: phanan/koel:9.15.0
    container_name: koel-9.15.0-app
    depends_on:
      - database
    ports:
      - "8143:80"
    environment:
      - DB_CONNECTION=mysql
      - DB_HOST=database
      - DB_USERNAME=koel
      - DB_PASSWORD=koeldb2026
      - DB_DATABASE=koel
      - MEMORY_LIMIT=1024
    volumes:
      - /opt/koel/.env:/var/www/html/.env
      - /opt/koel/music:/music
      - image_storage:/var/www/html/storage/app/public/images
      - search_index:/var/www/html/storage/search-indexes
    restart: unless-stopped

  database:
    image: mariadb:10.11
    container_name: koel-9.15.0-mariadb
    environment:
      - MYSQL_ROOT_PASSWORD=koelroot2026
      - MYSQL_DATABASE=koel
      - MYSQL_USER=koel
      - MYSQL_PASSWORD=koeldb2026
    volumes:
      - db:/var/lib/mysql
    restart: unless-stopped

volumes:
  db:
    driver: local
  image_storage:
    driver: local
  search_index:
    driver: local

配置要点解读:

  • DB_HOST=database:Compose 网络内服务名即主机名,Koel 经它连数据库;
  • environment 与 .env 中 DB_* 重复出现是有意的:环境变量优先级高于 .env 文件,双保险确保数据库连接指向容器网络内的 database 服务;
  • 三个 named volume 分别持久化数据库数据、图片存储(封面/头像)与搜索索引;.env 与 music/ 用 bind mount 便于在宿主机直接编辑与存取;
  • restart: unless-stopped 保证开机自启与异常退出自动拉起。

💡 技术拓展:容器数据持久化有 bind mount 与 named volume 两种主流方式——

方式原理适用场景
bind mount宿主目录直接映射进容器需要在宿主机直接查看/编辑的内容(如 .env、音乐库)
named volumeDocker 管理的存储区,位置与生命周期由 Docker 托管纯内部数据(如数据库文件、索引),迁移备份走 docker volume 命令

本方案按内容属性混用两者:可读性优先的用 bind mount,数据库等纯内部数据用 named volume。

4.3 启动与自动初始化

cd /opt/koel && docker compose up -d

实测回显:

[+] Running 5/5
 ✔ Network koel-stack_default      Created
 ✔ Volume "koel-stack_image_storage"  Created
 ✔ Volume "koel-stack_search_index"   Created
 ✔ Container koel-9.15.0-mariadb      Started
 ✔ Container koel-9.15.0-app          Started

首次启动时查看初始化日志(Koel 镜像会自动跑安装向导:迁移建表、生成密钥、建搜索索引):

docker compose logs koel | head -40

实测回显(节选,成功形态):

koel-9.15.0-app  | Running installer...
koel-9.15.0-app  |
koel-9.15.0-app  |                            KOEL INSTALLATION WIZARD.
koel-9.15.0-app  |
koel-9.15.0-app  |   Clearing caches ................................................ 6.45ms DONE
koel-9.15.0-app  |   .env file exists -- skipping .......................................... DONE
koel-9.15.0-app  |   Retrieving app key ............................................. 0.00ms DONE
koel-9.15.0-app  |   Using app key: base64:dBPglIMlH.. ..................................... DONE
koel-9.15.0-app  |   Migrating database ............................................ 17.49ms DONE
koel-9.15.0-app  |   Data already seeded -- skipping ....................................... DONE
koel-9.15.0-app  |   Linking storage ................................................ 0.04ms DONE
koel-9.15.0-app  |   Installing Koel scheduler ...................................... 4.74ms DONE
koel-9.15.0-app  |
koel-9.15.0-app  |    SUCCESS  All done!
koel-9.15.0-app  |
koel-9.15.0-app  |    INFO  🌟 A shiny Koel is now available at http://127.0.0.1.

看到 SUCCESS All done! 即初始化完成(40 张业务表已建好,可用 docker compose exec database mariadb -uroot -pkoelroot2026 koel -e "show tables" | wc -l 复核)。

⚠️ 若此环节出现 Generating app key FAIL,是 .env 对容器内 www-data 不可写所致,属本文实测踩过的坑,完整排障过程见第十一章。

4.4 创建管理员账号

浏览器打开 http://<服务器IP>:8143/,Koel 会呈现首次安装表单(设置管理员姓名、邮箱、密码与媒体库路径);提交后即以管理员身份进入播放器。这是官方安装文档定义的首个账号创建方式(表单为网页交互,无命令行回显),本实测实例即按此路径创建了 admin@koel.dev 管理员。

无法使用浏览器时,可先在数据库侧确认管理员行存在,再用 CLI 管理密码(命令实测见《koel 9.15.0 常用 CLI 命令与工具详解》):

docker compose exec database mariadb -uroot -pkoelroot2026 koel \
  -e "select id,name,email from users"

实测回显:

id	name	email
1	Koel	admin@koel.dev

忘记或需要重置演示账号密码时:

docker compose exec koel php artisan koel:admin:change-password admin@koel.dev

按提示两次输入新密码即可,实测回显(密码输入不回显):

Changing the user's password (ID: 1, email: admin@koel.dev)

 Your desired password:
 >

 Again, just to be sure:
 >

Alrighty, the new password has been saved. Enjoy! 👌

4.5 部署验证(服务存活 → 登录 → 出流)

验证 1:容器健康状态:

docker compose ps

实测回显:

NAME                  IMAGE                COMMAND                  SERVICE    CREATED        STATUS                    PORTS
koel-9.15.0-app       phanan/koel:9.15.0   "koel-entrypoint apa…"   koel       17 hours ago   Up 33 minutes (healthy)   0.0.0.0:8143->80/tcp, [::]:8143->80/tcp
koel-9.15.0-mariadb   mariadb:10.11        "docker-entrypoint.s…"   database   17 hours ago   Up 33 minutes             3306/tcp

验证 2:首页与登录:

curl -sI http://127.0.0.1:8143/ | head -4

实测回显:

HTTP/1.1 200 OK
Date: Thu, 29 Oct 2026 10:09:56 GMT
Server: Apache/2.4.68 (Debian)
X-Powered-By: PHP/8.4.27
curl -s -X POST http://127.0.0.1:8143/api/me \
  -H "Content-Type: application/json" -H "Accept: application/json" \
  -d '{"email":"admin@koel.dev","password":"q1w2e3r4"}'

实测回显(节选):

{"token":"21|ON3jMTFPatpbksIJYH9gXPnkD2cVpfFdUlrypVvnf2116560","audio-token":"22|q2F6dvlbO5F449FyGAHsWJwS29auuxiwFXyB117Y09ca929e"}

验证 3:音频流出流——用音频令牌请求播放端点,确认返回音频流(audio-token 是登录返回的音频令牌的机读部分,置于 Bearer 头):

curl -s -o /dev/null -w "HTTP %{http_code} type=%{content_type} size=%{size_download}\n" \
  -H "Authorization: Bearer 22|q2F6dvlbO5F449FyGAHsWJwS29auuxiwFXyB117Y09ca929e" \
  "http://127.0.0.1:8143/play/01a18387-397c-7202-9c81-bc169de43039"

实测回显:

HTTP 200 type=audio/mp3 size=481197

验证 4:扫描媒体库——把 mp3 放入 /opt/koel/music/ 后触发扫描(也可在 Web 界面点扫描):

docker compose exec koel php artisan koel:scan

实测回显:

   WARN  No song owner specified. Setting the first admin (Koel, ID 1) as owner.

   INFO  Scanning /music with 4 parallel workers.


 1/8 [===>------------------------]  12%
 4/8 [==============>-------------]  50%
 8/8 [============================] 100%

   INFO  Scanning completed!

  ⇂ 1 new or updated song(s)
  ⇂ 7 unchanged song(s)
  ⇂ 0 invalid file(s)

浏览器打开 http://<服务器IP>:8143/,用 admin@koel.dev / q1w2e3r4 登录,即可看到扫描入库的艺人与专辑并播放。

五、数据持久化说明

本方案的数据分落在 bind mount 与 named volume 两类载体(实测 docker volume ls):

docker volume ls --format '{{.Name}}' | grep koel

实测回显:

koel-stack_db
koel-stack_image_storage
koel-stack_search_index
载体宿主位置内容备份方式
bind:/opt/koel/.env宿主文件全部 Koel 配置直接 cp
bind:/opt/koel/music宿主目录音频原文件(核心资产)rsync/tar
volume:koel-stack_db/var/lib/docker/volumes/koel-stack_db/_dataMariaDB 全部数据mariadb-dump 逻辑备份(见第十章)
volume:koel-stack_image_storage同上规则封面/头像等图片docker run --rm -v 打包
volume:koel-stack_search_index同上规则tntsearch 全文索引可重建,无需备份(koel:search:import 一条命令重建)

数据库逻辑备份实测(导出量约 1482 行 SQL):

docker compose exec database sh -c 'mariadb-dump -uroot -pkoelroot2026 koel' | head -6

实测回显:

/*M!999999\- enable the sandbox mode */
-- MariaDB dump 10.19  Distrib 10.11.19-MariaDB, for debian-linux-gnu (x86_64)
--
-- Host: localhost    Database: koel
-- ------------------------------------------------------
-- Server version	10.11.19-MariaDB-ubu2204

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;

⚠️ 注意:媒体文件本身不走数据库,"音乐目录 + .env + 数据库转储"三样齐备即可完整重建一套 Koel;搜索索引属于可再生数据。

六、环境变量表

compose.yml 中直接注入的环境变量(优先级高于 .env 文件,改后需重建容器生效):

变量实测值作用
DB_CONNECTIONmysql数据库驱动(容器编排下固定 mysql/mariadb 均可)
DB_HOSTdatabase数据库主机 = compose 服务名
DB_USERNAME / DB_PASSWORDkoel / koeldb2026与 database 服务声明的凭据一致
DB_DATABASEkoel库名,与 MYSQL_DATABASE 一致
MEMORY_LIMIT1024扫描进程内存上限(MB)

.env 文件中的变量表(部署最小集,全量参数详解见《koel 9.15.0 配置参数详解》):

变量实测值作用
APP_NAME / APP_ENV / APP_DEBUGKoel / production / false应用标识、运行环境、调试开关
APP_URLhttp://127.0.0.1对外访问 URL(影响生成的绝对链接)
APP_KEY首次启动自动生成加密密钥,勿随意更换(更换后已发令牌需重登录)
MEDIA_PATH/music媒体库根目录(容器内路径)
STORAGE_DRIVERlocal存储驱动(s3/dropbox/webdav 为 Plus)
STREAMING_METHODphp流式方式;实测被镜像内置的 x-sendfile 覆盖,见排障实录
SCOUT_DRIVERtntsearch全文搜索驱动
APP_MAX_SCAN_TIME / MEMORY_LIMIT600 / 1024扫描超时(秒)与扫描内存上限(MB)
TRANSCODE_FLACfalseFLAC 实时转码开关(依赖 FFmpeg)
ALLOW_DOWNLOAD / BACKUP_ON_DELETEtrue / true下载开关与删除前备份
PODCASTS_ENABLED / RADIO_ENABLEDtrue / true播客与电台模块开关
CLEAN_URLS_ENABLED / EMBED_ENABLEDfalse / true伪静态 URL 与外链嵌入
MAIL_MAILER / BROADCAST_CONNECTIONlog / log邮件与广播驱动(log=写日志,个人部署够用)
CACHE_DRIVER / QUEUE_CONNECTION / SESSION_DRIVER / SESSION_LIFETIMEfile / sync / file / 120Laravel 基础驱动,默认即可

七、配置参数说明

三个最值得部署后立刻确认的参数:

  1. STREAMING_METHOD:.env 写 php,但实测运行时是 x-sendfile——镜像内置环境变量优先级更高。确认方式:
docker compose exec koel php artisan config:show koel.streaming | head -7

实测回显:

  koel.streaming .............................................................
  bitrate ................................................................ 128
  aac_fast .............................................................. true
  method .......................................................... x-sendfile
  ffmpeg_path ................................................ /usr/bin/ffmpeg
  transcode_flac ....................................................... false
  transcode_timeout ...................................................... 300

想让 .env 的值生效,需在 compose 的 environment: 里显式覆盖同名变量(或删除镜像内置值无法做到,只能覆盖)。

  1. MEDIA_PATH=/music:容器内媒体库根目录,与 compose 的 bind mount 目标一致;宿主机往 /opt/koel/music/ 放文件即可。

  2. DB_HOST=database:永远指向 compose 服务名,不要写成 IP(重建容器后 IP 会漂移,服务名解析始终有效)。

八、配置文件挂载

本方案挂载清单与目的:

容器内路径宿主来源挂载目的
/var/www/html/.env/opt/koel/.env配置文件外置,升级镜像不丢配置;需 www-data 可写(初始化向导要写 APP_KEY)
/music/opt/koel/music媒体库;只读场景可加 :ro,但会禁用上传写盘
/var/www/html/storage/app/public/imagesvolume: image_storage封面/头像持久化
/var/www/html/storage/search-indexesvolume: search_indextntsearch 索引持久化
/var/lib/mysql(database 服务)volume: db数据库数据持久化

⚠️ 注意:官方 Compose 示例还提供了 ./sql:/docker-entrypoint-initdb.d 挂载(放 CREATE DATABASE 类首初始化 SQL,由 MariaDB 镜像在数据目录为空时自动执行)。本方案用 MYSQL_DATABASE=koel 环境变量达成了同样的建库效果,故未引入该挂载;需要复杂首初始化逻辑时再加。

挂载正确性验证——宿主改 .env 容器内立即可见:

grep -c "STREAMING_METHOD" /opt/koel/.env && \
  docker compose exec koel grep -c "STREAMING_METHOD" /var/www/html/.env

实测回显:

1
1

九、等价 docker run

不使用 Compose 时,以下两条 docker run 与本文 compose.yml 等价(先建网络,再按依赖顺序启动):

docker network create koel-net

docker run -d --name koel-9.15.0-mariadb --network koel-net \
  -e MYSQL_ROOT_PASSWORD=koelroot2026 \
  -e MYSQL_DATABASE=koel \
  -e MYSQL_USER=koel \
  -e MYSQL_PASSWORD=koeldb2026 \
  -v koel-stack_db:/var/lib/mysql \
  --restart unless-stopped \
  mariadb:10.11

docker run -d --name koel-9.15.0-app --network koel-net \
  -p 8143:80 \
  -e DB_CONNECTION=mysql \
  -e DB_HOST=koel-9.15.0-mariadb \
  -e DB_USERNAME=koel \
  -e DB_PASSWORD=koeldb2026 \
  -e DB_DATABASE=koel \
  -e MEMORY_LIMIT=1024 \
  -v /opt/koel/.env:/var/www/html/.env \
  -v /opt/koel/music:/music \
  -v koel-stack_image_storage:/var/www/html/storage/app/public/images \
  -v koel-stack_search_index:/var/www/html/storage/search-indexes \
  --restart unless-stopped \
  phanan/koel:9.15.0

与 Compose 版的差异仅在 DB_HOST(docker run 没有 compose 服务名解析,直接用容器名)。日常管理仍建议用 Compose。

十、常用运维命令

# 服务状态(healthy 为镜像自带的健康检查结论)
docker compose ps

实测回显见 4.5 验证 1。

# 跟踪应用日志(Apache 访问日志 + 初始化输出)
docker compose logs -f koel

实测回显(节选,访问日志形态):

koel-9.15.0-app  | 10.89.62.1 - - [29/Oct/2026:10:10:06 +0000] "GET /api/me HTTP/1.1" 200 2024 "-" "curl/8.5.0"
koel-9.15.0-app  | 10.89.62.1 - - [29/Oct/2026:10:14:13 +0000] "POST /api/me HTTP/1.1" 200 486 "-" "curl/8.5.0"
# 重启应用服务(改 compose 配置后生效)
docker compose restart koel

# 升级 Koel 版本:改 compose.yml 中的镜像 tag 后执行
docker compose pull koel && docker compose up -d koel

升级实测要点:新版本容器启动时会自动执行 koel:init(含数据库迁移),日志出现 SUCCESS All done! 即升级完成;.env、音乐目录、三个数据卷均在挂载中,数据无损。

# 应用内 artisan 命令(扫描/体检/改密等,详见 CLI 详解篇)
docker compose exec koel php artisan koel:scan
docker compose exec koel php artisan koel:doctor

# 数据库备份与恢复
docker compose exec database sh -c 'mariadb-dump -uroot -pkoelroot2026 koel' > koel-backup.sql
docker compose exec -T database sh -c 'mariadb -uroot -pkoelroot2026 koel' < koel-backup.sql
# 停止与销毁(volume 不删;确认不要数据时再加 -v)
docker compose down

十一、常见问题(FAQ)

Q1:启动日志出现 Generating app key FAIL,页面打不开怎么办?

实测排障实录(现象 → 定位 → 解决 → 验证):

  • 现象:容器启动日志反复出现安装向导走到 Generating app key ... FAIL 后报错退出初始化:
  Clearing caches ................................................ 1.88ms DONE
  .env file exists -- skipping .......................................... DONE
  Generating app key ............................................. 0.31ms FAIL

   ERROR  Oops! Koel installation or upgrade didn't finish successfully.
  • 定位:查容器内应用错误日志:
docker compose exec koel tail -5 storage/logs/laravel.log

实测回显(关键行):

[2026-10-28 17:17:46] production.ERROR: ErrorException: file_put_contents(/var/www/html/.env): Failed to open stream: Permission denied in /var/www/html/vendor/laravel/framework/src/Illuminate/Filesystem/Filesystem.php:204

根因是 bind mount 的 .env 对容器内 www-data 用户不可写,初始化向导无法写回 APP_KEY。

  • 解决:宿主机上放开属主或权限后重建容器:
chown 33:33 /opt/koel/.env && chmod 644 /opt/koel/.env
docker compose restart koel
  • 验证:重启日志出现完整向导成功回显(实测):
  Retrieving app key ............................................. 0.00ms DONE
  Using app key: base64:dBPglIMlH.. ..................................... DONE
  Migrating database ............................................ 17.49ms DONE
   SUCCESS  All done!

Q2:.env 里改了 STREAMING_METHOD=php,为什么实际还是 x-sendfile?

镜像内置了环境变量 STREAMING_METHOD=x-sendfile(docker inspect koel-9.15.0-app 的 Config.Env 实测可见),Laravel 读取配置时环境变量优先于 .env 文件。要改流式方式,请在 compose 的 environment: 中显式覆盖:- STREAMING_METHOD=php,然后 docker compose up -d koel 重建。验证用 docker compose exec koel php artisan config:show koel.streaming。

Q3:koel:doctor 报 "This command cannot be run as root."?

docker compose exec koel php artisan koel:doctor

实测回显:

   ERROR  This command cannot be run as root.

该命令强制要求以非 root 运行(Koel 应用在容器内以 www-data 跑)。换用户执行即可:

docker compose exec -u www-data koel php artisan koel:doctor

实测回显(节选,全项 OK):

  Checking database connection ............................................ OK
  API is healthy .......................................................... OK
 [OK] Your Koel setup should be good to go!

Q4:页面能打开但媒体库是空的?

媒体入库需要扫描:确认 /opt/koel/music/ 已放文件且属主为 33(www-data 可读),然后 docker compose exec koel php artisan koel:scan。若扫描报 0 files,检查 MEDIA_PATH 是否为 /music、bind mount 是否指向了正确目录。

Q5:8143 端口被占用或想换端口?

只改 compose.yml 的宿主侧端口(如 "8080:80")后 docker compose up -d koel 重建即可;容器内 80 不动。同时建议同步更新 .env 的 APP_URL。

十二、参考链接