Ampache 常用命令与运维实战(核心篇)
bin/cli 扫描与元数据修复、Ampache/Subsonic 双 API 真实调用回显、流播放与转码对照、backup-db.sh 备份,附六条排障实录。
Ampache 常用命令与运维实战(核心篇)
曲库扫描、文件级元数据修复、两套 API 的真实调用与踩坑、数据库备份与导出——本文是 Ampache 8.3.0 的日常运维手册。所有命令与回显均来自真实服务器实测(环境为 《Ampache Docker Compose 部署实战》 搭建的单机站)。
CLI 体系总览
Ampache 8 的命令行入口统一为应用目录下的 bin/cli。直接执行不带参数会打印完整命令清单(按动词分组):
php /var/www/bin/cli
实测清单(节选,保留本文用到的组):
run
run:addCatalog Add a new catalog
run:updateCatalog Perform catalog actions for all files of a catalog. If no options are given, the defaults actions -ceagt are assumed
run:updateCatalogFile Perform catalog actions for a single file
run:updateCatalogFolder Perform catalog actions for a single folder
run:updateDb Update the database collation and charset
run:websocket Run the websocket server that listen-along broadcasting needs
show
show:debug Show a system status and environment report
show:version Version
export
export:albumArt Export album art
export:catalog Export catalog metadata to a file
export:databaseArt Export all database art to local_metadata_dir
其余组还有用户管理(add:user 等)与管理维护命令,php bin/cli <command> --help 可查每个命令的参数。两个最基础的体检命令实测:
php /var/www/bin/cli show:version
8.3.0
php /var/www/bin/cli show:debug
System
Version: 8.3.0
Structure: public
PHP: 8.5.12
Last cron: Never
Environment
[OK] PHP version
[OK] PDO
[OK] PDO MySQL
[OK] session
[OK] JSON
[OK] hash
[OK] intl
[OK] cURL
[OK] GD
[!!] memory limit
[OK] dependencies folder
Last cron: Never 说明计划任务(定时扫描/清理)从未跑过——生产环境需要自行配置 cron(Web 界面或 run:updateCatalog 的定时调用);[!!] memory limit 是默认 PHP 内存上限偏紧的提示,大曲库需调 memory_limit。
Catalog 扫描与媒体管理
建目录曲库
php /var/www/bin/cli run:addCatalog music /media
music 是曲库名,/media 是服务器上的媒体目录。建好后曲库登记进数据库但还没有歌曲,需要执行一次扫描。用数据库确认曲库已登记:
mariadb -uampache -pq1w2e3r4 ampache -e "select id,name,catalog_type,enabled from catalog"
实测输出:
id name catalog_type enabled
1 music local 1
扫描导入
php /var/www/bin/cli run:updateCatalog music -a -t
-a 收录新增文件,-t 重新生成目录结构;不带任何参数时默认执行 -ceagt(清理/变更/新增/校验/结构全套)。扫描完成的验证(查数据库):
songs
6
name year
Analog Dreams 2024
Field Notes 2023
6 首测试曲目、2 张专辑入库成功。常规校验扫描(读文件核对数据库):
php /var/www/bin/cli run:updateCatalog music -e -t -a
实测输出:
Update table mapping, counts and delete garbage data
local.catalog: update_folder_map
local.catalog: update_folder_counts
------------------
Time: 00:02
元数据修复后必须单文件重扫
真实场景:修了文件的标签(比如补年份),再跑上面的整库校验扫描,数据库里的元数据纹丝不动。实测对照:
修复 FLAC 文件的年份标签(ffmpeg 原地重写):
ffmpeg -i "05 - Deep Field.flac" -c copy -metadata date=2024 "05 - Deep Field.new.flac"
mv "05 - Deep Field.new.flac" "05 - Deep Field.flac"
ffprobe -v quiet -show_entries format_tags=date -of json "05 - Deep Field.flac"
{
"format": {
"tags": {
"date": "2024"
}
}
}
文件确实带上了 date=2024,但 run:updateCatalog music -e -t -a 之后数据库里该曲的 year 仍是 0。此时用单文件重扫强制重读:
php /var/www/bin/cli run:updateCatalogFile music "/media/05 - Deep Field.flac" -a -e
实测输出:
Reading File: "/media/05 - Deep Field.flac"
单文件重扫后专辑随之合并:
id name year songs
1 Field Notes 2023 3
4 Analog Dreams 2024 3
顺带两个实测教训:
run:updateCatalogFile的参数顺序是<catalogName> <filePath>,只传文件路径会把路径当曲库名解析;它也不认识-t,实测直接报Option "-t" not registered。- 专辑按「名称+艺术家+年份」聚合,年份缺失会拆出 year=0 的同名专辑——测试曲库 FLAC 补上年份重扫后 4 张专辑合并回 2 张,就是这个机制的直接体现。
导出曲库清单
php /var/www/bin/cli export:catalog /var/www/backup/catalog-export.csv -c 1
实测输出:
Exported catalog metadata to /var/www/backup/catalog-export.csv
导出的 CSV(实测内容):
ID,Title,Artist,Album,Length,Track,Year,"Date Added",Bitrate,Played,File
4,"Open Water","Northway Trio","Field Notes",0:40,0,2023,"10/28/26, 9:16 AM",15-VBR,,"/media/06 - Open Water.ogg"
3,"Silver Rain","Northway Trio","Field Notes",0:45,1,2023,"10/28/26, 9:16 AM",312-CBR,1,"/media/03 - Silver Rain.mp3"
1,"Northern Line","Northway Trio","Field Notes",0:45,2,2023,"10/28/26, 9:16 AM",312-CBR,,"/media/04 - Northern Line.mp3"
2,"Deep Field","Echo Valley","Analog Dreams",0:40,0,2024,"10/28/26, 9:16 AM",95-VBR,1,"/media/05 - Deep Field.flac"
6,"Morning Signal","Echo Valley","Analog Dreams",0:45,1,2024,"10/28/26, 9:16 AM",312-CBR,,"/media/01 - Morning Signal.mp3"
-c 0 导出全部曲库;第二个位置参数可选 itunes 格式。这份清单适合做曲库盘点与迁移比对。
Ampache API 实测
API 入口是 server/json.server.php(JSON)与 server/xml.server.php(XML)。除 ping 外所有方法都需要握手换取的 auth token。
握手(handshake)
认证串是双重 SHA-256:先算密码的 SHA-256,再拼接 Unix 时间戳求 SHA-256,即 auth = sha256(timestamp + sha256(password)),时间戳与服务器时差不能太大。
TS=$(date +%s)
H1=$(printf %s "q1w2e3r4" | sha256sum | cut -d' ' -f1)
AUTH=$(printf %s "${TS}${H1}" | sha256sum | cut -d' ' -f1)
curl -s "http://<服务器IP>:8137/server/json.server.php?action=handshake&user=admin×tamp=$TS&auth=$AUTH&version=8.0.0&client=quzuo-test"
实测回显(节选,字段落盘):
{
"auth": "056917369abf3d971e4106d5a2ec099f",
"streamtoken": "b228ac865ee81991f100b97de68812c11ef40405",
"api": "8.1.0",
"session_expire": "2026-10-28T10:44:00+00:00",
"update": "2026-10-28T09:27:38+00:00",
"max_song": 6,
"max_album": 4,
"max_artist": 2,
"songs": 6,
"albums": 4,
"artists": 2,
"genres": 2,
"catalogs": 1,
"username": "admin"
}
auth 就是后续请求的会话令牌(有效期默认 3600 秒,对应 session_length),streamtoken 是流播放链接里 ssid 参数的值。注意 8.3.0 已移除旧版可预测的 MD5(username) 会话,别再按老脚本硬编码。
方法调用与版本陷阱
拿到 token 后即可调数据方法。这里有一个版本陷阱:老教程里的 get_artists 在 API 6+ 已更名,实测直接得到 Invalid Request:
curl -s "http://<服务器IP>:8137/server/json.server.php?action=get_artists&auth=$AUTH&limit=2"
{
"error": {
"errorCode": "4705",
"errorAction": "get_artists",
"errorType": "system",
"errorMessage": "Invalid Request"
}
}
改用新名 artists:
curl -s "http://<服务器IP>:8137/server/json.server.php?action=artists&auth=$AUTH&limit=2"
实测返回两张专辑对应的两位艺术家(total_count: 2,genre 名为 Electronic/Folk)。单曲详情:
curl -s "http://<服务器IP>:8137/server/json.server.php?action=songs&auth=$AUTH&limit=1"
实测回显(保留实测字段值):
{
"id": "2",
"title": "Deep Field",
"artist": { "id": "2", "name": "Echo Valley", "prefix": "", "basename": "Echo Valley" },
"album": { "id": "4", "name": "Analog Dreams", "prefix": null, "basename": "Analog Dreams" },
"catalog": "1",
"bitrate": 97970,
"mime": "audio/flac",
"size": 489851,
"time": 40,
"url": "http://10.89.63.1:8137/play/index.php?ssid=b228ac865ee81991f100b97de68812c11ef40405&type=song&oid=2&uid=1&player=api&name=Echo%20Valley%20-%20Deep%20Field.flac",
"filename": "/media/05 - Deep Field.flac"
}
XML 格式在 xml.server.php,实测 action=artists&limit=1 回显片段:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<total_count>2</total_count>
<artist id="2">
<name><![CDATA[Echo Valley]]></name>
<genre id="2">
<name><![CDATA[Electronic]]></name>
</genre>
<albumcount>2</albumcount>
<songcount>3</songcount>
<art><![CDATA[http://10.89.63.1:8137/images/blankalbum.png]]></art>
</artist>
流播放
songs 返回的 url 即流地址,直接请求:
curl -s -o /dev/null -w "raw: HTTP %{http_code} type=%{content_type} size=%{size_download}\n" \
"http://<服务器IP>:8137/play/index.php?ssid=$STREAMTOKEN&type=song&oid=2&uid=1&player=api&format=raw"
curl -s -o /dev/null -w "mp3: HTTP %{http_code} type=%{content_type} size=%{size_download}\n" --max-time 90 -H "Range: bytes=0-" \
"http://<服务器IP>:8137/play/index.php?ssid=$STREAMTOKEN&type=song&oid=2&uid=1&player=api&format=mp3"
实测输出:
raw: HTTP 200 type=audio/flac size=489851
mp3: HTTP 200 type=audio/mpeg size=640883
format=raw 原样输出 FLAC;format=mp3 触发服务端转码(40 秒音频 640883 字节 ≈ 128 kbps)。转码开关与码率模板的配置关系见 《Ampache 配置参数详解》。
Subsonic API 实测
Subsonic 入口是 rest/<方法>.view,与 Ampache API 同源不同认证。认证有两个坑:
坑一:t/s(token+salt)认证用的不是登录密码,而是用户档案里的专用 Subsonic 密码。用登录密码算 MD5 token 实测被拒:
curl -s "http://<服务器IP>:8137/rest/ping.view?u=admin&t=00000000000000000000000000000000&s=abc123&v=1.16.1&c=quzuo-test&f=json"
{
"subsonic-response": {
"status": "failed",
"version": "1.16.1",
"type": "ampache",
"serverVersion": "8.3.0",
"openSubsonic": true,
"error": {
"code": 40,
"message": "Wrong username or password.",
"helpUrl": "https://ampache.org/api/subsonic"
}
}
}
要先在 Web 界面的用户资料里设置 Subsonic 专用密码,t = md5(专用密码 + salt) 才能通过。坑二之外,p= 直接传密码(或其十六进制编码)是最省事的实测路径:
curl -s "http://<服务器IP>:8137/rest/ping.view?u=admin&p=q1w2e3r4&v=1.16.1&c=quzuo-test&f=json"
{
"subsonic-response": {
"status": "ok",
"version": "1.16.1",
"type": "ampache",
"serverVersion": "8.3.0",
"openSubsonic": true
}
}
兼容层自报家门:协议 1.16.1、服务端 8.3.0、openSubsonic: true——主流 Subsonic 客户端均可直连。
常用浏览方法
# 艺术家索引
curl -s "http://<服务器IP>:8137/rest/getArtists.view?u=admin&p=q1w2e3r4&v=1.16.1&c=quzuo-test&f=json"
# 专辑列表
curl -s "http://<服务器IP>:8137/rest/getAlbumList2.view?u=admin&p=q1w2e3r4&v=1.16.1&c=quzuo-test&f=json&type=alphabeticalByName&size=4"
实测专辑列表(合并元数据修复后):
al-4 Analog Dreams | Echo Valley | songs: 3 | year: 2024
al-1 Field Notes | Northway Trio | songs: 3 | year: 2023
# 专辑内曲目
curl -s "http://<服务器IP>:8137/rest/getAlbum.view?u=admin&p=q1w2e3r4&v=1.16.1&c=quzuo-test&f=json&id=al-1"
实测回显(节选):
album: al-1 Field Notes year 2023
so-4 Open Water ogg 40
so-3 Silver Rain mp3 45
so-1 Northern Line mp3 45
搜索与播放统计:
curl -s "http://<服务器IP>:8137/rest/search3.view?u=admin&p=q1w2e3r4&v=1.16.1&c=quzuo-test&f=json&query=field"
curl -s "http://<服务器IP>:8137/rest/scrobble.view?u=admin&p=q1w2e3r4&v=1.16.1&c=quzuo-test&id=so-3"
scrobble 实测返回 status="ok",播放计数随之累加。
Subsonic 流播放与限速转码
curl -s -o s1.ogg -w "raw: HTTP %{http_code} type=%{content_type} size=%{size_download}\n" \
"http://<服务器IP>:8137/rest/stream.view?u=admin&p=q1w2e3r4&v=1.16.1&c=quzuo-test&id=so-4"
curl -s -o s2.mp3 -w "128k: HTTP %{http_code} type=%{content_type} size=%{size_download}\n" --max-time 90 \
"http://<服务器IP>:8137/rest/stream.view?u=admin&p=q1w2e3r4&v=1.16.1&c=quzuo-test&id=so-1&maxBitRate=128&format=mp3"
file s1.ogg s2.mp3
实测输出:
raw: HTTP 200 type=application/ogg size=82051
128k: HTTP 200 type=audio/mpeg size=1802610
s1.ogg: Ogg data, Vorbis audio, mono, 44100 Hz, ~96000 bps
s2.mp3: Audio file with ID3 version 2.4.0, contains: MPEG ADTS, layer III, v1, 320 kbps, 44.1 kHz, Monaural
两个实测发现:一是 Subsonic 端点不要带 f=json(流端点会被路由到 HTML 分支返回空 body);二是 maxBitRate=128 时回源参数确实带了 bitrate=128000,但落盘文件是 320 kbps——码率参数并未如请求预期传导,对码率敏感的部署要用 encode_args 定制并实测验证。
数据库备份与恢复
官方镜像自带 backup-db.sh,从 ampache.cfg.php 读取数据库凭据,无需传参:
docker exec ampache-8.3.0-web backup-db.sh
实测输出:
Backing up database 'ampache' to /var/www/backup/2026-10-28.sql
Backup complete: /var/www/backup/2026-10-28.sql
备份文件落在容器内 /var/www/backup,编排时已把宿主机 ./data/backup 挂到这里,落盘即得(实测目录):
2026-10-28.sql # backup-db.sh 产物
ampache-db-20261028.sql # 手工 mariadb-dump 产物
catalog-export.csv # export:catalog 产物
手工等价命令(需要恢复时用的凭据来自配置文件):
mariadb-dump -uampache -pq1w2e3r4 ampache > ampache-db-$(date +%Y%m%d).sql
实测产物 157669 字节,文件头自报服务端版本 11.8.9-MariaDB-ubu2404。恢复方向:
mariadb -uampache -pq1w2e3r4 ampache < ampache-db-20261028.sql
数据库之外别忘了两样:data/config(配置文件含数据库密码)与 data/media(音频本体)——官方文档原话是「Only the database is backed up this way」,其余用常规文件备份覆盖。另有 admin:exportSchema 可把当前库结构导出为种子 SQL,用于全新部署比对。
排障实录
以下六条全部来自本文实测过程的真实定位记录:
1. 整库 verify 不刷新已替换文件的元数据。 现象:ffmpeg 重写文件标签后 run:updateCatalog -e -t -a 照跑无误,但年份/专辑不变。定位:对比 ffprobe 文件标签与数据库 song 表字段值。解法:run:updateCatalogFile <catalog> <file> -a -e 单文件强制重读,重扫后同名专辑自动合并。
2. Subsonic 播放返回 HTTP 200 但 0 字节。 现象:rest/stream.view 返回 text/html 空 body,客户端侧表现为「连上了但播不出」。开启 debug 日志后看到关键两行:
(StreamingHandler) -> Stream proxy: http://localhost:8137/play/index.php?ssid=...&type=song&oid=1&uid=1&...
(StreamingHandler) -> Stream error: Failed to connect to localhost port 8137 after 0 ms: Could not connect to server
根因:Subsonic 流由服务端代理回源,回源地址取自请求 Host;测试时用 localhost:8137 访问,而服务进程内部访问不到这个地址。解法:用服务器自身可达的地址访问(本例 10.89.63.1:8137),日志立刻变为成功的 Stream proxy 记录,流正常输出。部署启示:发布给客户端的地址必须是服务端自己也能访问的地址(反向代理/防火墙场景重点核对)。
3. 转码 429 的定位与对照实验。 初始默认配置(transcode_flac 未授权、transcode_cmd 未启用)下请求 format=mp3 播放 FLAC 得到 HTTP 429 空响应。定位路径:配置语义(transcode_TYPE = {allowed|required|false},默认 false)→ 源码中播放动作的转码否决逻辑。修复后对照实测:
transcode OFF: HTTP 200 type=audio/flac size=489851 # transcode_cmd 可用但格式未授权时回退原格式
transcode ON: HTTP 200 type=audio/mpeg size=640883 # 授权后正常转码
即 429 出现在「请求转码格式 + 转码命令未就绪」的组合下;仅关闭格式授权而转码命令可用时,部分路径回退为原格式直出。修复方式:开启 transcode_flac = "allowed" 并确认 transcode_cmd = "ffmpeg"。
4. 用错 API 方法名得到 4705。 现象:action=get_artists 返回 errorCode 4705 Invalid Request。定位:源码确认 API 6+ 方法更名。解法:artists/songs 等新名;老集成脚本升级 8.x 前先过一遍 API 变更说明。
5. Subsonic t/s 认证 BADAUTH。 现象:md5(登录密码+salt) 得到 code 40 Wrong username or password.。定位:源码中 token 认证读取的是用户档案的专用 Subsonic 密码(subsonic secret),不是登录密码。解法:Web 界面用户资料里设置专用密码后重算 token,或直接用 p= 认证(内网环境)。
6. run:updateCatalogFile 参数顺序坑。 现象:只传文件路径时报参数错位、-t 选项直接抛 Option "-t" not registered。解法:该命令签名是 <catalogName> <filePath>,选项只有 -a/-e 等,整库动作才用 run:updateCatalog。
参考
- 站内系列:《Ampache 介绍与选型指南》、《Ampache Docker Compose 部署实战》、《Ampache 配置参数详解》
- 官方仓库:github.com/ampache/ampache(API 文档与源码)
- 官方镜像文档:github.com/ampache/ampache-docker(backup-db.sh、调试日志开关)