Audioserve 常用命令与运维实战(核心篇)
Audioserve 0.30.1 裸机运维核心篇:静态二进制与 Web 客户端安装、systemd 单元与必踩坑、服务生命周期与信号控制、API 与 positions 实测、转码链路与 ffmpeg 故障、TLS 直连、备份恢复升级与排障实录。
Audioserve 常用命令与运维实战(核心篇)
目标:以「裸 Linux 服务器 + 静态二进制 + systemd」形态交付 Audioserve 的生产运维手册——安装布局、服务生命周期、缓存管理、API 链路实测、转码链路、TLS、备份恢复与排障实录。与 Docker Compose 形态(见《Audioserve Docker Compose 部署实战》)二选一即可;本篇全部命令与回显来自 2026-10-28 在一台 Ubuntu 22.04 服务器上的真实实测。
一、环境信息
| 项目 | 取值 |
|---|---|
| 实测日期 | 2026-10-28 |
| 服务器系统 | Ubuntu 22.04(systemd 运行中) |
| 服务端版本 | audioserve 0.30.1 #561370e(GitHub Releases 静态构建,二进制 17.8 MB) |
| Web 客户端 | audioserve-web-release_v0.3.3.tgz(独立仓库 Releases) |
| 转码依赖 | apt 安装 ffmpeg 4.4.2-0ubuntu0.22.04.1 |
| 运行用户 | 专用系统用户 audioserve(nologin) |
| 目录约定 | 程序 /opt/audioserve,数据 /var/lib/audioserve,音频库 /srv/audiobooks(只读使用) |
| 监听端口 | 0.0.0.0:3000(内网实测入口映射为 8140) |
| 示例凭据 | 共享密钥 q1w2e3r4(生产请替换为强密钥) |
音频库为 ffmpeg 自造的测试收藏(作者/书名/章节目录结构,含 m4b 章节书与 .chapters CSV 侧车文件)。
二、安装:静态二进制 + Web 客户端
官方 Releases 提供 audioserve_static.tar.gz(静态链接构建,无运行时依赖),Web 客户端单独发布。实测安装序列:
cd /opt/work
curl -sL -o audioserve_static.tar.gz \
"https://github.com/izderadicka/audioserve/releases/download/v0.30.1/audioserve_static.tar.gz"
curl -sL -o audioserve-web.tgz \
"https://github.com/izderadicka/audioserve-web/releases/download/v0.3.3/audioserve-web-release_v0.3.3.tgz"
mkdir -p /opt/audioserve/client
tar xzf audioserve_static.tar.gz -C /opt/audioserve
tar xzf audioserve-web.tgz -C /opt/audioserve/client
mv /opt/audioserve/audioserve_static_v0.30.1/audioserve /opt/audioserve/audioserve
rmdir /opt/audioserve/audioserve_static_v0.30.1
useradd -r -s /usr/sbin/nologin -d /var/lib/audioserve audioserve
mkdir -p /var/lib/audioserve
chown -R audioserve:audioserve /var/lib/audioserve /opt/audioserve
落位核验(ls -la /opt/audioserve/ 实测):
/opt/audioserve/:
-rwxr-xr-x 1 audioserve audioserve 17812624 May 23 07:19 audioserve
drwxr-xr-x 3 audioserve audioserve 4096 Sep 11 2022 client
版本自检与编译特性(静态构建特性列表比 Docker 镜像多一个 static):
$ /opt/audioserve/audioserve --version
audioserve 0.30.1 #561370e (22.05.2026 01:40:12)
[INFO audioserve] Started audioserve 0.30.1 #561370e (22.05.2026 01:40:12) with features async-tar, async-zip, behind-proxy, chrono, cron, default, folder-download, shared-positions, static, symlinks, tls, websock
转码依赖安装(元数据解析不依赖它,转码依赖它):
apt-get update && apt-get install -y ffmpeg
ffmpeg -version | head -1
回显:
ffmpeg version 4.4.2-0ubuntu0.22.04.1 Copyright (c) 2000-2021 the FFmpeg developers
三、systemd 服务配置与启动
/etc/systemd/system/audioserve.service(实测最终版):
[Unit]
Description=Audioserve audiobook streaming server
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=audioserve
Group=audioserve
Environment=AUDIOSERVE_SHARED_SECRET=q1w2e3r4
Environment=RUST_LOG=info
ExecStart=/opt/audioserve/audioserve --client-dir /opt/audioserve/client --listen 0.0.0.0:3000 --data-dir /var/lib/audioserve /srv/audiobooks
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
启动与自启:
systemctl daemon-reload
systemctl enable --now audioserve
systemctl is-active audioserve
回显:
active
运行状态(systemctl status audioserve 实测——注意 Memory 一行,Rust 单二进制的常驻内存为 2.2 MiB):
● audioserve.service - Audioserve audiobook streaming server
Loaded: loaded (/etc/systemd/system/audioserve.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2026-10-28 09:14:29 UTC; 27min ago
Main PID: 4618 (audioserve)
Tasks: 20 (limit: 3172)
Memory: 2.2M
CPU: 161ms
就绪日志(journalctl -u audioserve -o cat --no-pager -n 3 实测):
[2026-10-28T09:14:29Z INFO audioserve] Started audioserve 0.30.1 #561370e (22.05.2026 01:40:12) with features async-tar, async-zip, behind-proxy, chrono, cron, default, folder-download, shared-positions, static, symlinks, tls, websock
[2026-10-28T09:14:29Z INFO collection::cache] Quick scan for collection "/srv/audiobooks" finished
[2026-10-28T09:14:29Z INFO audioserve] Server listening on 0.0.0.0:3000
两个必踩坑(首次部署大概率命中,均为实测原文):
-
不带
--client-dir从任意工作目录启动,服务立即退出:静态构建默认client_dir: client/dist是相对路径,裸服务器上该目录不存在:Error: Config/Arguments error: Error in config value client_dir: Directory with web client files "client/dist" does not exists or is not directory解法即单元中的
--client-dir /opt/audioserve/client(绝对路径)。Docker 镜像无此问题(工作目录/audioserve内自带client/dist)。 -
单元里不设
Environment=RUST_LOG=info时,journal 里几乎看不到日志(默认级别只有 error/warn)——不是服务异常,是日志被级别过滤了。显式注入RUST_LOG=info后上述 INFO 行才可见。
四、服务生命周期与缓存管理
systemctl restart audioserve # 重启(缓存快速核对,秒级就绪)
systemctl stop audioserve # 停止
journalctl -u audioserve -f # 跟踪日志
journalctl -u audioserve -o cat -n 50 # 最近 50 行(裸格式)
信号控制(发给主进程,容器形态为 docker exec <容器> kill -USR1 1):
| 信号 | 作用 | 实测回显 |
|---|---|---|
SIGUSR1 | 全量重扫集合缓存 | Received signal SIGUSR1 for full rescan of caches → Full scan for collection "/srv/audiobooks" finished |
SIGUSR2 | 立即写播放位置备份 | positions-backup.json 落盘(需已配置 --positions-backup-file) |
SIGTERM | 优雅退出 | Terminated on SIGTERM → Server finished |
大面积重组目录、改过 tags 参数(官方明确必须重扫)后执行:
kill -USR1 $(systemctl show -p MainPID --value audioserve)
五、API 实测(curl 运维视角)
认证拿 token(响应体即裸 token 文本,非 JSON;防重放的加盐模式为客户端生成随机盐 + sha256(密钥+盐) 一并提交,实测 200):
TOKEN=$(curl -s -X POST http://127.0.0.1:8140/authenticate \
-H 'Content-Type: application/json' -d '{"secret":"q1w2e3r4"}')
集合元数据(版本核对、能力开关一目了然):
{"version":"0.30.1","commit":"561370e (22.05.2026 01:40:12)","folder_download":true,"shared_positions":true,"count":1,"names":["audiobooks"]}
浏览目录(/0/folder/<路径>,路径 URL 编码):
{"is_file":false,"is_collapsed":false,"modified":1793178392613,"total_time":180,"files":[{"name":"001 - Chapter 1.mp3","path":"Clark, Arthur C./2001 A Space Odyssey/001 - Chapter 1.mp3","meta":{"duration":60,"bitrate":64,"tags":null},"mime":"audio/mpeg","section":null}],"subfolders":[],"cover":{"path":"Clark, Arthur C./2001 A Space Odyssey/cover.png","mime":"image/png"},"description":{"path":"Clark, Arthur C./2001 A Space Odyssey/description.txt","mime":"text/plain"},"tags":null}
搜索(/0/search?q=,子串命中目录):
{"files":[],"subfolders":[{"name":"Clark, Arthur C.","modified":1793178391877,"path":"Clark, Arthur C.","is_file":false,"finished":false}]}
播放位置(设备组维度)实测——写入后多端接续播放的核心 API:
curl -s -w '\nHTTP %{http_code}\n' -X POST 'http://127.0.0.1:8140/positions/demo-group' \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"timestamp":1793230000000,"collection":0,"folder":"Clark, Arthur C./2001 A Space Odyssey","file":"001 - Chapter 1.mp3","folder_finished":false,"position":42.5}'
回显:
HTTP 201
读取(GET /positions/demo-group/last 取该组最新一条,timestamp 为服务端落库时间):
{"timestamp":1793180709468,"collection":0,"folder":"Clark, Arthur C./2001 A Space Odyssey","file":"001 - Chapter 1.mp3","folder_finished":false,"position":42.5}
六、转码链路
依赖关系:原生播放(不带 trans 参数)直接流式返回磁盘文件,与 ffmpeg 无关;?trans=l/m/h 才 fork ffmpeg 子进程实时转 Opus。三档默认参数与自定义方法见《Audioserve 配置参数详解》。
转码请求实测(同一 60 秒 64k mp3 源):
raw HTTP 200 type=audio/mpeg size=480487
?trans=l HTTP 200 type=audio/ogg size=253962
?trans=m HTTP 200 type=audio/ogg size=475797
?trans=h HTTP 200 type=audio/ogg size=607560
拖动定位依赖的 HTTP Range(返回 206 分段):
curl -H 'Range: bytes=0-1023' .../0/audio/<path>
HTTP 206 size=1024
ffmpeg 缺失的真实故障(实测复现:把 ffmpeg 移走后请求 ?trans=l):
Internal server error
HTTP 500
服务端日志:
[ERROR audioserve::services::transcode] Cannot spawn child process: Os { code: 2, kind: NotFound, message: "No such file or directory" }
诊断口诀:原生 200、转码 500,先查 ffmpeg(command -v ffmpeg)。静态构建本身链接了 libavformat(时长/码率解析正常),所以只有转码挂——别被元数据正常的假象带偏。
七、TLS 内网直连
不用反代时可直接启用内置 TLS(rustls)。自签证书一条命令:
openssl req -newkey rsa:2048 -nodes -keyout /var/lib/audioserve/key.pem \
-x509 -days 365 -out /var/lib/audioserve/cert.pem \
-subj "/C=CN/ST=Test/L=Test/O=Demo/CN=audioserve"
单元 ExecStart 追加 --ssl-key /var/lib/audioserve/key.pem --ssl-cert /var/lib/audioserve/cert.pem 后重启,实测日志出现(监听地址跟随 --listen 取值):
[INFO audioserve] Server listening on 127.0.0.1:3003 with TLS
实测 curl -sk https://127.0.0.1:3003/ 返回 200(自签证书需 -k 忽略校验,生产请用正规证书);对 TLS 端口走纯 HTTP 则连接失败(无协议降级),客户端地址要用 https://。置于 nginx 后面则用 --behind-proxy(记录真实 IP)与 --url-path-prefix(路径前缀)。
八、备份与恢复
裸机形态的全部状态都在两个目录(实测布局):
/opt/audioserve/ # 程序 + 客户端(可重新下载,不备份亦可)
├── audioserve # 二进制 17.8 MB
└── client/ # audioserve-web v0.3.3
/var/lib/audioserve/ # 数据目录(--data-dir,全部状态)
├── audioserve.secret # 服务端盐文件,600 权限,32 字节(丢失=全部 token 失效)
├── col_db/ # sled 集合缓存 + 标签 + 播放位置
└── icons-cache/ # 封面缩略图缓存(可再生)
备份策略(实测可用的最小集合):
-
col_db/整目录冷备(systemctl stop后 tar); -
播放位置独立 JSON 快照:单元追加
--positions-backup-file /var/lib/audioserve/positions-backup.json --positions-backup-schedule 0 3 * * *(每天 03:00),随时可kill -USR2立即落盘;实测文件内容按 集合路径→目录→设备组 嵌套:{"/srv/audiobooks":{"Clark, Arthur C./2001 A Space Odyssey":{"demo-group":{"file":"001 - Chapter 1.mp3","timestamp":1793179051575,"position":42.5,"folder_finished":false}}}} -
audioserve.secret单独保一份——迁移时保留它,所有客户端无需重新登录。
恢复/迁移到新机:装好二进制与客户端 → 还原 /var/lib/audioserve(含 secret 与 col_db)→ 若用 JSON 恢复进度,首次以 --positions-restore=v1 --positions-backup-file <文件> 启动,恢复完成进程立即退出(官方 README:it will finish immediately after restoring positions, then run it again with your usual arguments)——去掉恢复参数再正常启动即可。
九、升级
cd /opt/work
VER=<目标版本tag,以 Releases 页最新稳定版为准> # 例如本次实测基线 v0.30.1
curl -sL -o audioserve_static.tar.gz \
"https://github.com/izderadicka/audioserve/releases/download/${VER}/audioserve_static.tar.gz"
tar xzf audioserve_static.tar.gz -C /opt/audioserve
mv /opt/audioserve/audioserve_static_v*/audioserve /opt/audioserve/audioserve.new
mv /opt/audioserve/audioserve.new /opt/audioserve/audioserve && chmod +x /opt/audioserve/audioserve
chown audioserve:audioserve /opt/audioserve/audioserve
systemctl restart audioserve && journalctl -u audioserve -o cat -n 3
要点:数据目录格式向后兼容,无需迁移;升级前照例 kill -USR2 落一份进度备份;回滚即换回旧二进制文件再重启。
十、排障实录
1. 服务退出:Error: Config/Arguments error: Error in config value client_dir: Directory with web client files "client/dist" does not exists or is not directory
静态构建未带 Web 客户端,且默认 client_dir 为相对路径。解法见第三节坑 1:单独下载 audioserve-web 发行包并用 --client-dir 绝对路径指定。
2. journal 里没有日志
未设 RUST_LOG=info(默认仅 error/warn 级别)。在 systemd 单元加 Environment=RUST_LOG=info 并 daemon-reload。官方帮助中 -d/--debug 已标注 Deprecated use RUST_LOG env. variable instead。
3. 原生播放正常、转码 500:Cannot spawn child process: Os { code: 2, kind: NotFound ... }
ffmpeg 未安装或不在 PATH(第六节实测复现原文)。apt-get install -y ffmpeg 后恢复,无需重启服务(每次转码新 fork 进程)。
4. systemctl enable --now 后秒退并反复重启
检查三处:数据目录属主(必须运行用户可写,否则 Error creating/reading secret: Permission denied);ExecStart 的音频目录是否真实存在(不存在时报 Error in config value base_dir: "<路径>" is not direcrory,注意官方拼写就是 direcrory);密钥是否通过 Environment= 传入。journalctl -u audioserve -o cat -n 20 的最后一行 Error 即答案。
5. Web 界面能开但封面缩略图质量差/慢
--icons-fast-scaling 是快速但糙的缩放(默认关闭、用 Lanczos3);大量大封面导致首次浏览慢时可清空 icons-cache/ 并确认 --icons-cache-size(默认 100 MB)未被打满。
十一、参考链接
- 官方 README(Installation / Collections cache / Security Best Practices):https://github.com/izderadicka/audioserve#readme
- Releases(静态构建下载):https://github.com/izderadicka/audioserve/releases
- audioserve-web 客户端发行包:https://github.com/izderadicka/audioserve-web/releases
- API 文档与 OAS3 规范:https://github.com/izderadicka/audioserve/blob/master/docs/api.md
- 本专栏姊妹篇:《Audioserve 介绍与选型指南》(https://www.quzuo.net/document/MeqWm6L3TUWt )、《Audioserve Docker Compose 部署实战》(https://www.quzuo.net/document/iQEgf4WeubHd )、《Audioserve 配置参数详解》(https://www.quzuo.net/document/z1jO2q3wn2aC )