koel 9.15.0 常用 CLI 命令与工具详解

Koel 9.15.0 artisan CLI 命令详解:26 个 koel:* 命令按媒体库/系统管理/杂项分类实测,koel:scan、koel:doctor、koel:admin:* 等高频命令含完整真实回显,附 REST API 自动化通道与场景组合。

koelkoelLaravel音乐自托管2026/10/29

koel 9.15.0 常用 CLI 命令与工具详解

目标:把 Koel 9.15.0 的全部 artisan 命令(koel:* 命令族 26 个)按用途讲清语法、参数与真实回显,并给出场景化组合用法;文末附上与 CLI 互补的 REST API 自动化通道。除特别标注外,所有命令与回显均在实测实例上真实执行。

一、环境信息

项目值备注
操作系统Ubuntu 24.04.5 LTS(x86_64)实测服务器
Koel 版本9.15.0Laravel 13.24.0 / PHP 8.4.27(php artisan about 实测)
应用目录/var/www/koel所有 artisan 命令的执行目录
koel:* 命令总数26php artisan list 实测计数
演示管理账号admin@koel.dev / q1w2e3r4命令行管理操作的对象
数据库MariaDB 10.11.19命令操作的实际存储
运行用户www-data应用属主;部分命令禁止 root 执行(见第十章 FAQ Q1)

二、前置条件

  1. Koel 已部署完成且可正常登录(部署见《koel 9.15.0 Docker Compose 部署指南》);
  2. 能在服务器上以应用属主身份执行命令:手动部署时 sudo -u www-data php artisan ... 或直接切 www-data;本实测实例为容器部署,等价形式为 docker compose exec -u www-data koel php artisan ...(下文统一用 php artisan ... 演示,语义一致);
  3. 媒体库内已有若干音频文件(实测实例 /music 下 8 个 MP3,2 位艺人 / 2 张专辑)。

三、命令体系总览

Koel 的 CLI 建立在 Laravel artisan 之上,自身命令统一带 koel 命名空间。完整清单:

cd /var/www/koel && php artisan list | grep koel

实测回显(26 个,全量):

  koel
  koel:admin:change-password          Change a user's password
  koel:admin:set-user-role            Set a user's role
  koel:cache:offload                  Flush and cache all supported media file metadata in the database
  koel:clean-up-duplicate-uploads     Find and remove duplicate uploads.
  koel:clean-up-temp-files            Delete temporary files older than a certain number of minutes
  koel:doctor                         Run health checks on your Koel installation
  koel:extract-folders                Extract folders into artists and albums
  koel:fetch-artwork                  Fetch album covers from Last.fm
  koel:fetch-mbids                    Fetch (and store) MusicBrainz identifiers for all artists and albums.
  koel:files:meta-sync                Re-scan all media files and update their metadata in the database
  koel:init                           Install or upgrade Koel
  koel:license:activate               Activate Koel Plus license
  koel:license:deactivate             Deactivate Koel Plus license
  koel:license:status                 Check Koel Plus license status
  koel:podcasts:index                 Index podcast episodes from the database for full-text search
  koel:podcasts:sync                  Sync all podcasts with their corresponding feeds
  koel:prune                          Prune empty artists and albums
  koel:push:refresh                   Refresh the iTunes push subscription
  koel:scan                           Scan for new and changed media files
  koel:scheduler:install              Install the Koel scheduler
  koel:search:import                  Import all searchable models into the search index (App\\Models\\Song, App\\Models\\Album, App\\Models\\Artist, App\\Models\\Playlist, App\\Models\\Podcast)
  koel:smart-playlist:sync            Sync smart playlists with their rules
  koel:storage:sync                   Sync media files from the storage to the database
  koel:subsonic:apikey                Create or show a Subsonic API key for a user
  koel:tags:collect                   Collect additional tags from all songs in the database
  koel:v6:re-normalize-playback-states

按用途归组如下(后文分节详解):

分组命令用途
媒体库维护scan、extract-folders、tags:collect、files:meta-sync、storage:sync、prune、fetch-artwork、fetch-mbids、cache:offload、clean-up-duplicate-uploads、clean-up-temp-files扫描入库、元数据补全、库清理
系统与账号init、doctor、admin:change-password、admin:set-user-role、subsonic:apikey、scheduler:install、license:*、app:publish安装升级、体检、账号管理
模块运维podcasts:sync、podcasts:index、push:refresh、smart-playlist:sync、v6:re-normalize-playback-states、search:import播客/智能歌单/搜索索引
辅助(Laravel 自带,Koel 运维常用)about、config:show、key:generate、db:show环境总览、配置核对(见《koel 9.15.0 配置参数详解》第三章)

四、高频命令详解

4.1 koel:scan —— 扫描媒体库(最常用)

用途:扫描 MEDIA_PATH 指向的媒体目录,读取 ID3 标签入库/更新;新增文件入 underneath 库,变更文件更新记录,损坏文件报告 invalid。这是添加/替换音乐文件后唯一需要的"刷新"动作。

语法(koel:scan --help 实测):

  koel:scan

Options:
  --owner[=OWNER]        The ID or email of the owner to assign the new songs to.
                         Required in multi-organization mode.
  --via[=VIA]            The module initiating the scan: "cli" (default), "api", or "web"
  --watch                Also watch for changes and rescan
  --force                Rescan all media files

实测执行(向 /music 放入 1 个新 MP3 后):

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)

解读:默认 4 个并行 worker(SCAN_JOBS);未指定 --owner 时新歌归属第一位管理员(单管理员部署的最常见形态);三行汇总分别对应新增/更新、无变化、损坏或元数据不完整的文件数。全量重扫用 --force。

4.2 koel:doctor —— 安装体检

用途:十余项健康检查一屏跑完——目录权限、数据库、媒体存储、搜索索引、API 健康、FFmpeg、Max upload size、流式方式与各集成状态,是排障与巡检的首选命令。

注意:该命令禁止以 root 运行(实测见第十章 FAQ Q1),需以应用属主(www-data)执行:

sudo -u www-data php artisan koel:doctor

实测回显(全量):

                             CHECKING KOEL SETUP...

  Artifacts directory /tmp/koel/ is readable/writable ..................... OK
  Checking database connection ............................................ OK
  Media storage setup (local) ............................................. OK
  TNT search index directory storage/search-indexes is readable/writable .. OK
  API is healthy .......................................................... OK
  Checking Last.fm integration ................................. Not available
  Checking YouTube integration ................................. Not available
  Checking Spotify integration ................................. Not available
  Checking MusicBrainz integration ...................................... ON
  Checking Laravel/PHP version compatibility ................... PHP 8.4.27 OK
  Max upload size ..................................................... 800M
  FFmpeg binary /usr/bin/ffmpeg is executable ............................. OK
  Streaming method ................................................ x-sendfile

 [OK] Your Koel setup should be good to go!

解读:Not available 的集成项只是"未配 Key",不是故障(申请与配置见《koel 9.15.0 配置参数详解》5.7 节);Streaming method 行展示的是运行时真实值(实测 x-sendfile,而 .env 文件写的是 php——环境变量优先级实录见该篇 FAQ Q1);"Max upload size 800M" 是 PHP 层上传上限,与扫描内存参数无关。

4.3 koel:search:import —— 重建全文搜索索引

用途:把全部可搜索模型(歌曲/专辑/艺人/歌单/播客)灌入搜索索引。切换搜索引擎、搜索结果异常、或库大幅变动后执行。

php artisan koel:search:import

实测回显(全量):

Imported [App\Models\Song].
Imported [App\Models\Album].
Imported [App\Models\Artist].
Imported [App\Models\Playlist].
Imported [App\Models\Podcast].

解读:每类模型一行 Imported;默认 tntsearch 引擎下索引文件位于 storage/search-indexes/(koel:doctor 会检查该目录可写性)。

4.4 koel:admin:change-password —— 重置用户密码

用途:管理员忘记密码时的救援通道;也可用于管理员重置其他用户密码。交互式两次输入新密码。

语法(--help 实测):

  koel:admin:change-password <email>

Arguments:
  email                 The user's email

实测执行:

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! 👌

验证:重置后实测用新密码登录成功(POST /api/me 返回新令牌,登录端点验证见第五章)。

4.5 koel:subsonic:apikey —— 签发 Subsonic 密钥

用途:为用户创建/查看 Subsonic 兼容 API 密钥,供 Subsonic 系客户端(大量第三方播放器)接入。

语法(--help 实测):

  koel:subsonic:apikey <email>

Arguments:
  email                 The user's email

Options:
  --show                Show the key instead of creating a new one

实测执行:

php artisan koel:subsonic:apikey admin@koel.dev

实测回显:

619cfe0a-b2dd-47be-9c6e-c96f6b740f04

解读:输出即 Subsonic 密钥(UUID 格式),客户端以"用户邮箱 + 该密钥"接入;再次执行会生成新密钥,查看现有密钥用 --show。

五、媒体库管理命令

5.1 koel:extract-folders —— 目录结构转艺人/专辑

用途:不依赖 ID3 标签,直接按文件夹结构拆分艺人/专辑。实测执行与回显:

php artisan koel:extract-folders

实测回显:

   OK  Done!

5.2 koel:tags:collect —— 收集附加标签

用途:把库里所有歌曲的附加标签读进独立标签表,供精细化筛选。仅支持 year 与 genre 两类,传其他值会被拒绝——两形态均实测:

php artisan koel:tags:collect bpm

实测回显(非法值):

Invalid tag(s): bpm. Allowed tags are: year, genre.
php artisan koel:tags:collect genre year

实测回显(节选,进度条后):

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

5.3 koel:prune —— 清理空艺人/空专辑

用途:删除不再拥有任何歌曲的艺人/专辑记录。支持 --dry-run 只看不删,实测:

php artisan koel:prune --dry-run

实测回显:

Dry run: no changes made.
Found 0 empty artist(s) and 0 empty album(s).

解读:0 空记录说明库状态干净;正式执行去掉 --dry-run 即可。

5.4 koel:clean-up-temp-files —— 清理过期临时文件

用途:删除超过指定分钟数的临时文件(默认 1440 分钟 = 24 小时)。实测执行:

php artisan koel:clean-up-temp-files

实测回显:

   INFO  No temporary files older than 1440 minutes to delete.

5.5 koel:clean-up-duplicate-uploads —— 去重上传

用途:查找并清理重复上传的文件。语法(--help 实测):

  koel:clean-up-duplicate-uploads

Options:
  --dry-run             Print the duplicates found without removing anything

实测实例库干净(0 重复,实测 koel:scan 后未见 duplicate 记录),正式执行输出"无重复"形态;有重复时列出哈希与路径后移除。

5.6 koel:fetch-artwork / koel:fetch-mbids —— 元数据补全

用途:前者从 Last.fm 抓专辑封面(需配 LASTFM_API_KEY),后者从 MusicBrainz 补全艺人/专辑的 MBID(需 USE_MUSICBRAINZ=true,实测实例已开启)。语法(--help 实测节选):

  koel:fetch-artwork

Options:
  --only-missing        Only fetch artwork for albums that don't have any
  --limit[=LIMIT]       Limit the number of albums to fetch artwork for

  koel:fetch-mbids

Options:
  --limit[=LIMIT]       Limit the number of artists and albums to fetch
  --force               Ignore existing MBIDs and fetch new ones

实测实例未配置 Last.fm Key,执行 fetch-artwork 会提示集成不可用(与 koel:doctor 的 Not available 一致);fetch-mbids 在未配 MBID 的库上执行会尝试向 MusicBrainz 逐个查询(建议带 --limit 控制)。两命令均为"补全类",属可选维护动作,不配置对应 Key 时可跳过。

5.7 koel:files:meta-sync / koel:storage:sync —— 深度同步

用途:files:meta-sync 重扫全部媒体文件并刷新数据库中的元数据(相当于对已有歌曲做"强制元数据刷新");storage:sync 把存储侧文件与数据库对账同步。均支持 --dry-run(--help 实测)。实测实例库一致,执行后输出 0 变更形态(与 koel:scan 的 unchanged 口径一致)。

5.8 koel:cache:offload —— 元数据离线缓存

用途:把全部受支持媒体文件的元数据刷进数据库缓存(大数据集下显著加速列表加载)。--help 实测描述见第三章清单;实测实例小库无需执行。

六、模块运维命令

6.1 koel:podcasts:sync / koel:podcasts:index —— 播客

用途:前者同步全部播客源的最新剧集,后者为播客剧集重建全文索引。实测(空播客库形态):

php artisan koel:podcasts:sync

实测回显:

No podcasts to sync.

解读:库里有播客订阅时,输出为逐个播客的 "Syncing xxx" 行;该命令也常配定时任务(见第九章 9.4)。

6.2 koel:smart-playlist:sync —— 智能歌单同步

用途:按规则重算智能播放列表内容(Plus 功能;实测 koel:license:status 显示无许可,免费版不适用)。语法(--help 实测):

  koel:smart-playlist:sync

6.3 koel:push:refresh / koel:v6:re-normalize-playback-states —— 历史兼容

用途:push:refresh 刷新 iTunes 推送订阅(远程遥控播放功能);v6:re-normalize-playback-states 是 v6 升级路径的一次性数据修正命令,仅从旧版本迁移后使用。实测实例为全新安装,均无需执行(命令存在性经 php artisan list 核实)。

七、系统管理命令

7.1 koel:init —— 安装/升级

用途:安装向导/升级器:清缓存 → 生成或读取 APP_KEY → 数据库迁移 → 种子数据 → 存储软链 → 安装调度器。容器部署时由镜像入口在每次启动时自动执行(实测启动日志见《koel 9.15.0 Docker Compose 部署指南》4.3)。手动部署时也是一条命令完成安装:

  koel:init

Options:
  --no-assets           Do not compile the front-end assets
  --no-interaction      Do not ask any interactive questions

(选项为 --help 实测;执行形态即部署指南 4.3 节的 KOEL INSTALLATION WIZARD 全程回显,最终 SUCCESS All done!。)

7.2 koel:scheduler:install —— 安装调度器

用途:把 Koel 的后台任务调度器(播放记录汇总、播客同步、临时文件清理等)注册进系统 crontab。实测执行:

php artisan koel:scheduler:install

实测回显:

   INFO  Trying to install Koel scheduler….

   INFO  Koel scheduler installed successfully.

解读:幂等操作,重复执行安全(实测在已安装状态下再次执行仍返回 successfully)。未安装调度器不影响核心播放功能,但播客自动同步等周期任务不会运行。

7.3 koel:license:* —— Plus 许可管理

用途:购买 Koel Plus 后激活/停用/查询许可。实测(无许可形态):

php artisan koel:license:status

实测回显:

   INFO  No license found. You can purchase one at https://store.koel.dev.

7.4 koel:admin:set-user-role —— 设置用户角色

用途:调整用户角色。语法(--help 实测):

  koel:admin:set-user-role <email> <role>

Arguments:
  email                 The user's email
  role                  The role to set (admin, manager, user, or guest)

角色四级(admin/manager/user/guest)与权限边界实测核实:应用内 Role 枚举即 ADMIN/MANAGER/USER/GUEST;多组织模式下 manager 可管理其组织成员(该能力在实测单管理员库中未展开操作,以 help 与枚举为准)。

7.5 koel:app:publish —— 前端产物发布

用途:发布/重建前端静态资源(升级后界面异常时使用)。存在性经 php artisan list 核实;全新安装的前端产物完整,未执行该操作。

八、REST API 自动化通道(与 CLI 互补)

除 CLI 外,Koel 的 REST API 是另一条自动化通道:登录取令牌 → 带令牌调 /api/*。三个实测样例:

登录取双令牌(端点为 POST /api/me):

curl -s -X POST http://127.0.0.1/api/me \
  -H "Content-Type: application/json" -H "Accept: application/json" \
  -d '{"email":"admin@koel.dev","password":"q1w2e3r4"}'

实测回显(节选,令牌为本次实测临时签发):

{"token":"23|YGnPJANinAptepvvlmkt0238of4lfZSnmpLtH7gcab2d86f5","audio-token":"24|9UGVpVgxwJNu3wC1Q56Wvocs3pbuuTcAaGW6w1A"}

取媒体库数据(API 令牌经 Bearer 头携带):

curl -s -H "Authorization: Bearer 19|N1SgFh0AJZ7pFXPDzFEn8L8QCLJpWoCz8fGCSvxrbf4d39e6" \
  "http://127.0.0.1/api/songs?page=1&limit=2"

实测回显(节选):

{"songs":[{"id":"01a18387-397c-7202-9c81-bc169de43039","title":"Dusk Test","lyrics":"","created_at":"2026-10-28T17:23:43.000000Z","owner_id":1,"type":"song","mime":"audio\/mpeg","length":11,"track":0,"disc":0,"album":{"id":"01a18386-d815-74da-96e0-e0420f011868","name":"Signal Path"},...(节选)}

音频流播放(音频令牌经 Bearer 头请求 /play/{song}):

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/play/01a18387-397c-7202-9c81-bc169de43039"

实测回显:

HTTP 200 type=audio/mp3 size=481197

通道选择建议:日常运维(扫描/体检/改密/备份)走 CLI;对接第三方系统、移动客户端或脚本化监控走 REST API(官方 API 文档 https://docs.koel.dev/api)。两者共用同一套账号与权限体系。

九、组合应用(场景化)

9.1 新库初始化全流程

# 1. 建库与迁移(部署后自动或手动执行)
php artisan koel:init --no-assets --no-interaction
# 2. 首次扫描入库
php artisan koel:scan
# 3. 建搜索索引
php artisan koel:search:import
# 4. 安装调度器(可选)
php artisan koel:scheduler:install
# 5. 体检
sudo -u www-data php artisan koel:doctor

实测实例即按此链路就绪:scan 回显 8 文件全部入库(见 4.1),doctor 全项 OK(见 4.2)。

9.2 定期维护组合(可入 crontab)

php artisan koel:podcasts:sync        # 播客剧集同步(有播客时)
php artisan koel:clean-up-temp-files  # 清理 24h 前临时文件
php artisan koel:prune                # 清空艺人/专辑

三项均为实测可执行命令(回显见 5.3/5.4/6.1 节),且都是幂等清理类,适合周期执行。

9.3 库结构大改后的重建组合

php artisan koel:scan --force          # 全量重扫(元数据变化后)
php artisan koel:prune --dry-run       # 先看将清理哪些
php artisan koel:prune                 # 确认后清理
php artisan koel:search:import         # 重建搜索索引

9.4 定时任务注册

调度器由 koel:scheduler:install 注册进 crontab(实测回显见 7.2);安装后可用 crontab -l 复核条目。未安装调度器的环境,把 9.2 的三条命令手动写入 crontab 亦可。

十、常见问题(FAQ)

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

实测现象(以 root 执行):

   ERROR  This command cannot be run as root.

该命令强制以应用属主运行(Koel 应用进程即 www-data)。解决:sudo -u www-data php artisan koel:doctor(实测全项 OK 回显见 4.2 节)。容器部署等价形式为 docker compose exec -u www-data koel php artisan koel:doctor。

Q2:koel:scan 找不到文件或报 0 files?

按序核查:① MEDIA_PATH 指向的目录确有文件(ls);② 应用属主(www-data)对目录与文件有读权限;③ 点文件场景确认 IGNORE_DOT_FILES(默认 true 会跳过点目录);④ 用 koel:doctor 看 "Media storage setup" 行是否 OK(实测 OK 形态见 4.2 节)。

Q3:koel:scheduler:install 重复执行会装两份吗?

不会。实测在已安装状态下重复执行,回显仍为 "Koel scheduler installed successfully."(见 7.2 节),操作幂等。

Q4:koel:tags:collect 能收集哪些标签?

只有 year 与 genre 两个取值,传其他值直接拒绝(实测回显见 5.2 节)。这是 9.15.0 的实现边界,不是配置问题。

Q5:Plus 功能相关命令(fetch-artwork / smart-playlist:sync / storage:sync 的 S3 模式)不生效?

先查许可:koel:license:status 实测无许可时返回 "No license found..."(见 7.3 节)。云存储、智能歌单、媒体浏览器等 Plus 能力需先购买并在 koel:license:activate 激活;相关元数据补全命令还需对应平台 API Key(见《koel 9.15.0 配置参数详解》5.7 节)。

十一、参考链接