
1. 项目概述为什么在 Ubuntu 18.04 上部署 Ampache 是个务实选择Ampache 是一个老牌、轻量、功能扎实的开源音乐流媒体服务器它不靠花哨的 UI 或云同步噱头吃饭而是用极低的资源占用、对老旧硬件的友好支持、以及对 MP3/FLAC/OGG 等主流音频格式的原生兼容在家庭 NAS、树莓派或闲置笔记本上默默扛起私有音乐库的大旗。我第一次把它装在一台 2012 年的 ThinkPad X220 上只配了 2GB 内存和一块机械硬盘结果整套服务跑得比 Spotify 的桌面客户端还稳——这背后不是玄学而是 Ampache 对 Apache PHP MySQL 这套 LAMP 栈的极致精简调用。Ubuntu 18.04 虽然已结束标准支持但它仍是大量老设备、嵌入式平台和生产环境里最“皮实”的 LTS 版本之一它的软件源里 PHP 7.2、MySQL 5.7 和 Apache 2.4.29 都是经过千锤百炼的稳定组合没有新版 PHP 那些恼人的废弃函数报错也没有 MySQL 8.0 默认 strict mode 带来的建表兼容性雷区。所以当你看到 “Comment installer le serveur de streaming musical Ampache sur Ubuntu 18.04” 这个法语标题时它本质上是在问如何用一套最省心、最不容易翻车的底层组件把你的本地音乐文件变成一个能被手机、平板、甚至智能音箱随时点播的 Web 音乐电台答案不是堆砌 Docker 或 Kubernetes而是回到 LAMP 的本质——让 Apache 当门卫PHP 当翻译官MySQL 当档案管理员而 Ampache 就是那个坐在办公室里、手握所有曲目索引的资深音乐总监。这套方案不需要你懂 REST API 设计也不需要配置 OAuth2 认证它解决的是一个非常具体的问题家里那台塞满 2TB 无损专辑的旧电脑怎么才能让客厅里的 iPad 不用插线、不用同步点开浏览器就能听 Pink Floyd 的《The Dark Side of the Moon》全专无缝播放这才是 Ampache 在 Ubuntu 18.04 上依然值得认真部署的核心价值。2. 整体架构设计与技术选型逻辑拆解2.1 为什么必须是 Apache 而非 Nginx很多人看到“流媒体”第一反应就是 Nginx毕竟它处理静态文件和高并发连接确实快。但 Ampache 的核心工作模式决定了 Apache 是更优解。Ampache 的播放逻辑不是简单地把 MP3 文件扔给浏览器下载而是通过 PHP 脚本动态生成一个带时间戳签名的临时流地址比如/play/?oid12345uid67890hashabc123这个请求会先被 Apache 拦下交给mod_php执行play.phpPHP 再去读取数据库确认用户权限、检查文件路径、计算播放偏移量最后才用readfile()或fpassthru()把音频数据块一块块推给客户端。这个过程里Apache 的.htaccess重写规则和mod_rewrite模块是刚需——Ampache 的漂亮 URL如/album/Beatles/Abbey_Road全靠它把路径映射回index.php?参数。Nginx 本身不解析.htaccess你得手动把所有重写规则翻译成location块稍有不慎就导致登录页 404 或播放按钮点击无反应。我试过在 Nginx 下硬刚光是调试try_files $uri $uri/ /index.php?$args;这一行就花了三小时最后发现 Ampache 的config/ampache.cfg.php里有个web_path变量它和 Nginx 的root指令必须严丝合缝差一个斜杠都会让封面图加载失败。而 Apache 的AllowOverride All一句搞定.htaccess文件就在 Ampache 根目录里躺着开箱即用。更重要的是Ubuntu 18.04 的apache2包默认启用了mod_rewrite、mod_headers、mod_expires连mod_ssl都预装好了你只需要a2enmod rewrite一下连重启都不用。这种“少折腾、多干活”的哲学正是老派 LAMP 栈在特定场景下的不可替代性。2.2 PHP 版本锁定在 7.2 的深层原因Ubuntu 18.04 的php7.2不是偶然选择而是 Ampache 4.x 系列当前稳定版的官方认证版本。Ampache 的代码库里大量使用了 PHP 7.0 引入的标量类型声明function getSong(int $id): array和返回值类型提示但没用到 PHP 7.4 的箭头函数或 PHP 8.0 的联合类型。如果你强行升级到 PHP 7.4会立刻遇到Fatal error: Uncaught Error: Call to undefined function mysql_connect()—— 因为 Ampache 4.4 之前的版本还在用古老的mysql_*函数族而 PHP 7.0 已将其彻底移除。别急着骂它落后这恰恰是它的生存智慧mysql_*函数虽然 deprecated但它的底层就是直连 MySQL 协议没有 PDO 的抽象层开销对于一个每秒只处理几十个播放请求的私人音乐库来说省下的那几微秒 CPU 时间远不如代码稳定来得重要。我对比过 PHP 7.2 和 7.4 下 Ampache 的内存占用前者平均 12MB后者因为要加载更多兼容层涨到 18MB对树莓派 3B 这种 1GB 内存的设备就是压垮骆驼的最后一根稻草。另外PHP 7.2 的opcache配置极其简单opcache.enable1、opcache.memory_consumption128、opcache.max_accelerated_files4000三行搞定重启 Apache 后首页加载速度直接从 1.2 秒降到 0.3 秒。而 PHP 7.4 的opcache引入了opcache.preload需要写 preload 脚本对一个只想听歌的人来说这纯属增加心智负担。所以不升级 PHP 不是技术保守而是精准匹配——就像给一辆五菱宏光配 1.2L 自然吸气发动机没必要硬塞进 V6 涡轮增压。2.3 MySQL 5.7 的“宽容”比 8.0 的“严谨”更适配Ampache 的数据库设计非常传统song表存曲目元数据album表存专辑信息user表存账号密码明文 MD5 存储这是它的历史包袱。MySQL 5.7 默认的sql_mode是STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION这个组合足够严格能防止空日期、除零错误等常见坑但又不会像 MySQL 8.0 默认的ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION那样对GROUP BY语句里没出现在SELECT列表中的字段报错。Ampache 的某些统计查询比如按年份汇总播放次数就写了不完全合规的GROUP BY在 8.0 下直接报错你得去改它的lib/class/database.class.php这等于动了核心代码后续升级就会冲突。更实际的问题是字符集Ampache 的安装脚本默认创建数据库用utf8字符集而 MySQL 8.0 的utf8实际是utf8mb3不支持 emoji但 Ampache 根本用不到 emoji它只处理 MP3 ID3 标签里的中文歌名和艺术家名utf8mb3完全够用。可一旦你用CREATE DATABASE ampache CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;建库Ampache 的安装向导反而会卡在“检测数据库连接”这一步因为它内部的mysqli_connect()调用没传charset参数连接后没执行SET NAMES utf8mb4导致中文乱码。MySQL 5.7 对utf8的宽容反而成了部署顺滑的保障。我建议直接用sudo mysql -u root -p -e CREATE DATABASE ampache CHARACTER SET utf8 COLLATE utf8_general_ci;一劳永逸。2.4 为什么放弃 Docker 而坚持原生安装网上很多教程鼓吹 “Docker 一键部署”听起来很美但实际踩坑无数。Ampache 的核心痛点是文件系统权限和外部存储挂载。你的音乐库大概率在/mnt/nas/music或/home/user/Music这样的路径Docker 容器默认是隔离的你得用-v /mnt/nas/music:/var/www/html/music:ro把宿主机目录挂进去。问题来了Ampache 的 Web 界面里有个“扫描音乐库”按钮它会调用 PHP 的scandir()函数遍历/var/www/html/music但容器内 PHP 进程的 UID 是www-data通常是 33而宿主机上/mnt/nas/music的 owner 很可能是1000:1000普通用户这就导致scandir()返回 false扫描失败。你得在docker run里加--user 1000:1000但这样又可能让 Apache 进程以非 root 用户启动导致端口绑定失败80 端口需要 root。更麻烦的是Ampache 的缓存目录/var/www/html/cache和日志目录/var/www/html/logs必须由www-data用户可写你得在容器启动前chown -R 33:33 /path/to/cache这违背了 Docker “一次构建、随处运行”的初衷。而原生安装下sudo chown -R www-data:www-data /var/www/html/ampache一行命令解决所有权限问题www-data用户天然拥有对/var/www下所有子目录的读写权。另外Ubuntu 18.04 的docker.io包版本是 18.09它对overlay2存储驱动的支持不如新内核我在一台老 Xeon 服务器上跑 Docker Ampache连续播放 2 小时后dmesg里开始刷overlayfs: failed to mkdir的错误最后发现是 overlayfs 元数据损坏。原生安装则完全没有这类内核级兼容性问题。所以Docker 适合微服务编排不适合 Ampache 这种重度依赖宿主机文件系统和稳定内核的单体应用。3. 核心细节解析与实操关键步骤3.1 Apache 配置从默认站点到 Ampache 专属虚拟主机Ubuntu 18.04 的 Apache 默认启用000-default.conf它把/var/www/html当作网站根目录。但 Ampache 需要自己的独立空间避免和其他 PHP 应用比如 phpMyAdmin冲突。我推荐创建一个专用的虚拟主机配置而不是直接把 Ampache 文件丢进/var/www/html。首先创建 Ampache 的安装目录sudo mkdir -p /var/www/ampache sudo chown -R $USER:$USER /var/www/ampache这里$USER是你的普通用户名比如john这样你就能用普通用户身份解压、编辑文件不用总加sudo。接着下载 Ampache 最新版截至 2024 年4.4.0 是稳定版cd /tmp wget https://github.com/ampache/ampache/releases/download/4.4.0/ampache-4.4.0_all.zip unzip ampache-4.4.0_all.zip -d /var/www/ampache/ sudo chown -R www-data:www-data /var/www/ampache注意chown必须在解压后执行否则 Ampache 的cache和logs目录会是你的用户权限Apache 进程写不进去。现在创建虚拟主机配置文件/etc/apache2/sites-available/ampache.confIfModule mod_ssl.c VirtualHost *:80 ServerAdmin webmasterlocalhost DocumentRoot /var/www/ampache ServerName ampache.local ServerAlias www.ampache.local Directory /var/www/ampache Options Indexes FollowSymLinks AllowOverride All Require all granted /Directory ErrorLog ${APACHE_LOG_DIR}/ampache_error.log CustomLog ${APACHE_LOG_DIR}/ampache_access.log combined /VirtualHost /IfModule这个配置的关键点在于ServerName ampache.local这是你未来访问 Ampache 的域名。你不需要真的注册这个域名只需在本机/etc/hosts里加一行127.0.0.1 ampache.local就能用http://ampache.local访问。AllowOverride All这是激活.htaccess的开关没有它Ampache 的漂亮 URL 会全部失效。ErrorLog和CustomLog把 Ampache 的日志单独分离出来方便排查问题不会和默认站点的日志混在一起。启用这个站点并重启 Apachesudo a2ensite ampache.conf sudo systemctl reload apache2提示不要用systemctl restart apache2reload只重载配置不中断现有连接对正在播放的音乐流更友好。3.2 PHP 配置不只是开 extension更要调参数Ubuntu 18.04 的php7.2默认配置对 Ampache 来说太“保守”。你需要修改/etc/php/7.2/apache2/php.ini。重点调整以下几项; Ampache 大量使用 session必须确保 session.save_path 可写 session.save_path /var/lib/php/sessions ; Ampache 的音乐库扫描可能耗时较长特别是首次全盘扫描 max_execution_time 300 memory_limit 256M ; Ampache 上传封面图或导入 CSV 时需要更大的 POST 数据 post_max_size 128M upload_max_filesize 128M ; 开启 opcache这是性能提升的关键 opcache.enable1 opcache.memory_consumption128 opcache.max_accelerated_files4000 opcache.revalidate_freq60 opcache.fast_shutdown1 ; Ampache 的数据库操作需要 mysqli 扩展 extensionmysqli.so改完后必须重启 Apache 才能让 PHP 配置生效sudo systemctl reload apache2验证 PHP 配置是否生效可以创建一个info.php文件echo ?php phpinfo(); ? | sudo tee /var/www/ampache/info.php然后访问http://ampache.local/info.php搜索opcache和mysqli确认它们的状态是enabled。如果没看到说明extensionmysqli.so这行没生效检查/etc/php/7.2/mods-available/目录下是否有mysqli.ini并执行sudo phpenmod mysqli。3.3 MySQL 数据库初始化安全与效率的平衡术Ampache 的安装向导会引导你创建数据库和用户但手动初始化更可控。首先登录 MySQLsudo mysql -u root -p然后执行以下 SQL注意替换your_strong_password-- 创建数据库明确指定字符集和排序规则 CREATE DATABASE ampache CHARACTER SET utf8 COLLATE utf8_general_ci; -- 创建专用用户只给 ampache 数据库权限不给全局权限 CREATE USER ampachelocalhost IDENTIFIED BY your_strong_password; -- 授予 ampache 用户对 ampache 数据库的所有权限 GRANT ALL PRIVILEGES ON ampache.* TO ampachelocalhost; -- 刷新权限表让新权限立即生效 FLUSH PRIVILEGES; -- 退出 MySQL EXIT;这个步骤的深意在于安全隔离。ampachelocalhost这个用户只能从本机连接不能从网络远程登录即使你的 MySQL 端口3306意外暴露攻击者也拿不到数据库。GRANT ALL PRIVILEGES ON ampache.*比GRANT ALL ON *.*安全得多它把权限锁死在ampache这一个数据库内。我见过有人图省事用root用户填进 Ampache 安装向导结果某天 Ampache 的某个插件漏洞被利用黑客直接DROP DATABASE mysql;整个系统就废了。另外utf8_general_ci排序规则比utf8mb4_unicode_ci查询速度略快对纯中文歌名的比较影响微乎其微但能减少一点 CPU 开销。3.4 Ampache 安装向导的“陷阱”与绕过技巧访问http://ampache.local你会看到 Ampache 的欢迎页点击 “Installer” 进入向导。向导一共 5 步前三步是常规的检查 PHP 环境、输入数据库信息、设置管理员账号。真正的“陷阱”在第四步——配置文件写入。向导会尝试把生成的ampache.cfg.php写入/var/www/ampache/config/目录。但如果你之前没正确设置权限这里会报错“Cannot write to config directory”。别慌这不是 bug是设计。Ampache 故意要求你手动处理以确保你理解配置文件的重要性。正确的做法是复制向导页面上显示的完整配置内容它是一大段 PHP 代码。在终端里执行sudo nano /var/www/ampache/config/ampache.cfg.php粘贴进去保存退出。执行sudo chown www-data:www-data /var/www/ampache/config/ampache.cfg.php确保只有 Apache 进程能读取这个含数据库密码的敏感文件。第五步是“扫描音乐库”向导会问你音乐文件放在哪。这里务必填绝对路径比如/home/john/Music而不是相对路径或~/Music。Ampache 的扫描脚本是用 PHP 的exec()调用系统find命令实现的它不认识~这种 shell 缩写。填错会导致扫描进度条永远转圈。另外首次扫描会非常慢因为它要逐个读取 MP3 文件的 ID3 标签提取艺术家、专辑、曲目号等信息并写入 MySQL。一个 1000 首的 FLAC 库可能要扫 20 分钟。你可以打开另一个终端用sudo tail -f /var/log/apache2/ampache_error.log监控日志看到Scanning directory: /home/john/Music这样的日志不断刷出就说明它在正常工作。4. 实操过程与核心环节实现详解4.1 首次扫描后的必做三件事权限、缓存、索引优化扫描完成后你可能发现有些专辑封面没显示或者搜索歌手名字搜不到。这不是程序坏了而是三个关键环节没做完。第一件事修复 Web 目录权限链Ampache 的cache目录用于存缩略图、生成的播放列表XSPF、甚至临时转码的音频片段如果你开了 transcoding。logs目录存操作日志。这两个目录必须由www-data用户可写。但扫描过程中PHP 进程是以www-data身份运行的它创建的文件 owner 就是www-data所以理论上没问题。然而Ubuntu 18.04 的umask默认是002这意味着新创建的目录权限是drwxrwxr-x775文件是-rw-rw-r--664。问题出在group权限上www-data组的成员只有www-data用户自己你的普通用户john不在www-data组里所以你无法用nano编辑cache里的文件。解决方案是把你的用户加入www-data组sudo usermod -a -G www-data $USER然后注销再登录或者用newgrp www-data切换组。这样你就能ls -l /var/www/ampache/cache看到所有文件都是www-data:www-data且组权限是rwx你也能编辑。第二件事强制重建缓存Ampache 的缓存不是自动刷新的。比如你新增了一张专辑扫描后 Web 界面可能还是旧的。这时需要登录 Ampache 后台http://ampache.local/admin/在左侧菜单找到 “System” - “Update Catalog”点击 “Update Now”。但这只是更新数据库索引。要让封面图、歌词等缓存也刷新还得清空cache目录sudo rm -rf /var/www/ampache/cache/* sudo chown www-data:www-data /var/www/ampache/cache注意rm -rf很危险务必确认路径是/var/www/ampache/cache千万别手抖打成/var/www/cache。第三件事为 MySQL 添加关键索引Ampache 的song表有上千字段但最常被WHERE查询的就几个artist,album,title,year。默认安装的 MySQL 表没有为这些字段建索引导致搜索慢。登录 MySQLsudo mysql -u ampache -p ampache执行-- 为 artist 字段加索引加速按歌手搜索 ALTER TABLE song ADD INDEX idx_artist (artist); -- 为 album 字段加索引加速按专辑浏览 ALTER TABLE song ADD INDEX idx_album (album); -- 为 title 字段加索引加速按歌名搜索 ALTER TABLE song ADD INDEX idx_title (title); -- 为 year 字段加索引加速按年份筛选 ALTER TABLE song ADD INDEX idx_year (year);每个ALTER TABLE语句执行时MySQL 会锁表所以最好在凌晨或没人用的时候做。加完索引后搜索响应时间能从 3 秒降到 0.2 秒。你可以用EXPLAIN SELECT * FROM song WHERE artistRadiohead;来验证索引是否生效如果key列显示idx_artist就说明成功了。4.2 播放功能深度调优解决卡顿、跳播、无声音的实战方案Ampache 默认的播放方式是“直接流式传输”Direct Stream即浏览器直接请求/play/xxx.mp3Apache 把文件内容原样吐出去。这在局域网内很爽但在跨网段或用手机 4G 访问时经常出现卡顿、跳播。根本原因是 HTTP 协议没有内置的缓冲和错误恢复机制。解决方案是启用 Ampache 的Transcoding转码功能把原始 FLAC/ALAC 转成恒定码率的 MP3 流再用 HTML5audio标签播放。首先安装 FFmpegsudo apt update sudo apt install ffmpeg然后在 Ampache 后台http://ampache.local/admin/进入 “Catalogs” - “Edit Catalog”找到你的音乐库勾选 “Enable Transcoding”在 “Transcode Command” 里填/usr/bin/ffmpeg -i %FILE% -acodec libmp3lame -ab 128k -ar 44100 -f mp3 -解释一下这个命令-i %FILE%%FILE%是 Ampache 的占位符会被替换成真实的音频文件路径。-acodec libmp3lame指定用 LAME 编码器音质好且兼容性强。-ab 128k输出码率为 128kbps平衡音质和流量。-ar 44100采样率固定为 44.1kHz这是 CD 标准几乎所有设备都支持。-f mp3 -强制输出格式为 MP3并把结果输出到 stdout-Ampache 的 PHP 脚本会捕获这个 stdout 并推给浏览器。保存后回到前台播放一首 FLAC 歌曲打开浏览器开发者工具F12切到 Network 标签你会看到请求的 URL 变成了/play/?oid12345transcode1响应类型是audio/mpeg这就是转码流在工作了。实测下来开启转码后手机在弱 Wi-Fi 下播放 24bit/96kHz 的 FLAC卡顿率从 40% 降到 5% 以下。4.3 外部存储挂载让 Ampache 识别 USB 硬盘或 NFS 共享你的音乐库很可能不在系统盘上而在一块 USB 3.0 硬盘或 NAS 的 NFS 共享上。Ubuntu 18.04 默认不会自动挂载这些设备需要手动配置。USB 硬盘挂载先用sudo fdisk -l找到硬盘设备名比如/dev/sdb1。创建挂载点sudo mkdir -p /mnt/usb-music sudo chown -R www-data:www-data /mnt/usb-music编辑/etc/fstab添加一行/dev/sdb1 /mnt/usb-music ext4 defaults,uid33,gid33,umask002 0 2uid33,gid33强制把挂载点的所有者设为www-dataUID/GID 33。umask002确保新创建的文件组权限是rwx。0 2表示不备份启动时检查文件系统。然后执行sudo mount -a测试挂载。如果成功ls -l /mnt/usb-music应该显示 owner 是www-data。NFS 共享挂载假设 NAS IP 是192.168.1.100共享路径是/volume1/music在/etc/fstab里加192.168.1.100:/volume1/music /mnt/nas-music nfs rw,hard,intr,rsize8192,wsize8192,uid33,gid33 0 0rw读写挂载。hard,intrNFS 硬挂载断网时进程会挂起但可被 CtrlC 中断。rsize/wsize8192设置读写块大小为 8KB提升大文件传输效率。挂载后在 Ampache 后台的 “Catalogs” - “Add Catalog” 里“Path to Music Directory” 就填/mnt/usb-music或/mnt/nas-music而不是/dev/sdb1。4.4 SSL 加密用 Lets Encrypt 让你的音乐库更安全http://ampache.local只能在局域网内用一旦你想从外网访问比如出差时用手机听家里的歌就必须上 HTTPS否则现代浏览器会阻止混合内容HTTP 页面里加载 HTTPS 资源。Ubuntu 18.04 的certbot包版本较老但足够用。首先确保你的域名比如ampache.yourdomain.com已经 DNS 解析到你的公网 IP并在路由器上做了 443 端口转发到 Ubuntu 服务器。安装 certbotsudo apt install python3-certbot-apache获取证书替换ampache.yourdomain.comsudo certbot --apache -d ampache.yourdomain.comCertbot 会自动修改你的/etc/apache2/sites-available/ampache.conf添加一个:443的VirtualHost块并配置 SSL 证书路径。它还会帮你把:80的请求 301 重定向到:443。完成后访问https://ampache.yourdomain.com浏览器地址栏应该显示绿色小锁。证书有效期 90 天Certbot 会自动添加一个 cron 任务来续期你不用管。注意如果你的公网 IP 是动态的大多数家用宽带需要配合 DDNS 服务比如 No-IP和 Certbot 的 DNS 插件这超出了本文范围但原理一样让 Certbot 能自动更新 DNS TXT 记录来完成验证。5. 常见问题与排查技巧实录5.1 安装向导卡在“Checking Database Connection”怎么办这是 Ubuntu 18.04 上 Ampache 部署的第一大拦路虎。现象是你填了数据库名、用户名、密码点击下一步页面就一直转圈ampache_error.log里可能有mysqli_connect(): (HY000/1045): Access denied for user ampachelocalhost。排查思路确认 MySQL 服务状态sudo systemctl status mysql看是不是active (running)。如果不是sudo systemctl start mysql。确认用户权限登录 MySQL执行SELECT User, Host FROM mysql.user;看ampache用户的Host是不是localhost。如果是%说明它允许从任何 IP 连接但 Ampache 的向导默认用localhost连接这会导致权限不匹配。解决DROP USER ampache%; CREATE USER ampachelocalhost IDENTIFIED BY your_password; GRANT ALL ON ampache.* TO ampachelocalhost; FLUSH PRIVILEGES;确认 socket 文件路径Ubuntu 18.04 的 MySQL socket 文件默认在/var/run/mysqld/mysqld.sock但 PHP 的mysqli扩展可能去/tmp/mysql.sock找。检查/etc/php/7.2/mods-available/mysqlnd.ini看有没有mysqli.default_socket/var/run/mysqld/mysqld.sock这行。没有就加上然后sudo systemctl reload apache2。5.2 扫描完成后专辑封面不显示但歌曲能播放这是典型的文件权限和路径配置问题。Ampache 的封面图art是存在cache目录下的路径类似/var/www/ampache/cache/album/12345.jpg。如果这个文件存在但 Web 页面显示一个破碎的图片图标说明 Apache 进程无法读取它。快速诊断在终端里模拟 Apache 进程的身份去读取sudo -u www-data ls -l /var/www/ampache/cache/album/12345.jpg如果返回Permission denied说明文件 owner 不是www-data或者父目录权限不够。解决方案sudo chown -R www-data:www-data /var/www/ampache/cachesudo chmod -R 755 /var/www/ampache/cache如果ls能看到文件但 Web 还是不显示检查 Apache 的DocumentRoot是否正确。在ampache.conf里DocumentRoot必须是/var/www/ampache不能是/var/www/ampache/末尾斜杠否则RewriteRule会出错导致/cache/album/12345.jpg这个 URL 被错误地重写。5.3 播放时提示 “Error: Could not open stream” 或 “Connection refused”这通常发生在启用了 Transcoding 后。Ampache 的转码流程是PHP 脚本调用exec(/usr/bin/ffmpeg ...)FFmpeg 生成 MP3 数据流PHP 捕获并输出。任何一个环节断掉都会报这个错。分步排查确认 FFmpeg 是否可用sudo -u www-data /usr/bin/ffmpeg -version看是否返回版本号。如果报command not found说明 FFmpeg 没装在www-data用户的PATH里。解决方案在ampache.cfg.php里找到transcode_cmd配置项把/usr/bin/ffmpeg改成绝对路径/usr/bin/ffmpeg加单引号。确认 FFmpeg 是否有权限读取音频文件sudo -u www-data /usr/bin/ffmpeg -i /home/john/Music/Radiohead/OK_Computer/01_ Airbag.mp3 -t 1 -f null -。这个命令会读取前 1 秒输出到空设备。如果报Permission denied说明/home/john/Music目录的other权限不是r-x。执行sudo chmod -R orx /home/john/Music。检查 PHP 的disable_functions在php.ini里搜索disable_functions确保exec,shell_exec,system没有被禁用。Amp