koel 9.15.0 Docker Compose 部署指南
Koel 9.15.0 Docker Compose 部署实战:phanan/koel + MariaDB 10.11 双服务编排、.env 准备与权限排障、数据持久化、等价 docker run 与升级备份,全部步骤实测。
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) | 实测服务器 |
| Docker | 29.9.2 | docker --version 实测 |
| Docker Compose | v5.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 运行时;自带初始化入口脚本与健康检查 |
| 自行从源码构建 | ❌ 无必要 | 官方镜像已含前端编译产物,自建徒增维护成本 |
官方镜像实测关键行为(本文步骤会逐一用到):
- 入口脚本
koel-entrypoint:以 www-data 用户运行koel-init,后者在检测到.env后自动执行php artisan koel:init --no-assets --no-interaction——即数据库迁移与初始化在每次容器启动时自动完成,无需手动进容器跑安装命令; - 健康检查:镜像内置
curl -f http://localhost/sw.js,每 300 秒一次(docker inspect实测),docker compose ps会显示(healthy); - 内置环境变量:镜像自带
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。
三、前置条件
- 服务器已安装 Docker 与 Compose 插件(验证命令与实测回显):
docker --version && docker compose version
实测回显:
Docker version 29.9.2, build a82e528
Docker Compose version v5.6.1
- 服务器 8143 端口未被占用(如被占用换宿主侧端口即可):
ss -ltnp | grep 8143 || echo "port 8143 free"
实测回显:
port 8143 free
- 音乐文件若干(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
- 目录规划:本文使用
/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 volume Docker 管理的存储区,位置与生命周期由 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/_data | MariaDB 全部数据 | 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_CONNECTION | mysql | 数据库驱动(容器编排下固定 mysql/mariadb 均可) |
| DB_HOST | database | 数据库主机 = compose 服务名 |
| DB_USERNAME / DB_PASSWORD | koel / koeldb2026 | 与 database 服务声明的凭据一致 |
| DB_DATABASE | koel | 库名,与 MYSQL_DATABASE 一致 |
| MEMORY_LIMIT | 1024 | 扫描进程内存上限(MB) |
.env 文件中的变量表(部署最小集,全量参数详解见《koel 9.15.0 配置参数详解》):
| 变量 | 实测值 | 作用 |
|---|---|---|
| APP_NAME / APP_ENV / APP_DEBUG | Koel / production / false | 应用标识、运行环境、调试开关 |
| APP_URL | http://127.0.0.1 | 对外访问 URL(影响生成的绝对链接) |
| APP_KEY | 首次启动自动生成 | 加密密钥,勿随意更换(更换后已发令牌需重登录) |
| MEDIA_PATH | /music | 媒体库根目录(容器内路径) |
| STORAGE_DRIVER | local | 存储驱动(s3/dropbox/webdav 为 Plus) |
| STREAMING_METHOD | php | 流式方式;实测被镜像内置的 x-sendfile 覆盖,见排障实录 |
| SCOUT_DRIVER | tntsearch | 全文搜索驱动 |
| APP_MAX_SCAN_TIME / MEMORY_LIMIT | 600 / 1024 | 扫描超时(秒)与扫描内存上限(MB) |
| TRANSCODE_FLAC | false | FLAC 实时转码开关(依赖 FFmpeg) |
| ALLOW_DOWNLOAD / BACKUP_ON_DELETE | true / true | 下载开关与删除前备份 |
| PODCASTS_ENABLED / RADIO_ENABLED | true / true | 播客与电台模块开关 |
| CLEAN_URLS_ENABLED / EMBED_ENABLED | false / true | 伪静态 URL 与外链嵌入 |
| MAIL_MAILER / BROADCAST_CONNECTION | log / log | 邮件与广播驱动(log=写日志,个人部署够用) |
| CACHE_DRIVER / QUEUE_CONNECTION / SESSION_DRIVER / SESSION_LIFETIME | file / sync / file / 120 | Laravel 基础驱动,默认即可 |
七、配置参数说明
三个最值得部署后立刻确认的参数:
- 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: 里显式覆盖同名变量(或删除镜像内置值无法做到,只能覆盖)。
-
MEDIA_PATH=/music:容器内媒体库根目录,与 compose 的 bind mount 目标一致;宿主机往
/opt/koel/music/放文件即可。 -
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/images | volume: image_storage | 封面/头像持久化 |
| /var/www/html/storage/search-indexes | volume: search_index | tntsearch 索引持久化 |
| /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。
十二、参考链接
- 官方 Docker 部署文档:https://docs.koel.dev/installation(Docker 一节即本篇 Compose 方案的官方口径)
- 官方镜像构建仓库:https://github.com/koel/docker
- 镜像仓库(Docker Hub):https://hub.docker.com/r/phanan/koel
- Koel 源码仓库:https://github.com/koel/koel
- 项目定位与同类选型对比见站内《koel 9.15.0 介绍与选型指南》
- 配置变量全集与取值说明见站内《koel 9.15.0 配置参数详解》;容器内 artisan 命令全集见站内《koel 9.15.0 常用 CLI 命令与工具详解》