Icecast Docker Compose 部署实战
Icecast 2.5.0 从零部署实录:本地构建 systemd 制品与编排文件逐段详解、ffmpeg 推流与 curl 拉流 icy-* 响应头验证、admin Dashboard 与 3 路听众计数闭环、401/404/503/端口冲突四则排障实录。
Icecast Docker Compose 部署实战
目标:在一台真实服务器上,用 Docker Compose 从零把 Icecast 2.5.0 网络电台服务器跑起来——本地构建 systemd 制品、编写编排文件、启动并验证初始化日志、用 ffmpeg 生成测试音频推流、用 curl 拉流核对 icy-* 响应头、登录 admin 管理面核对 stats 与听众计数,最后给出四则真实排障记录。本文全部命令与输出均为 2026-10-28 在 Ubuntu 24.04 服务器上的逐行实测照抄。产品定位与选型背景见本专栏《Icecast 介绍与选型指南》,icecast.xml 逐项参数说明见《Icecast 配置参数详解》,日常运维操作见《Icecast 常用命令与运维实战》。
一、部署前置条件
本章先确认服务器的软硬件基线、端口与目录规划,避免「抄完编排文件却起不来」的返工。
1.1 运行环境
本次实测服务器的基线环境如下(逐行实测输出):
$ grep PRETTY /etc/os-release
PRETTY_NAME="Ubuntu 24.04.5 LTS"
$ uname -m
x86_64
$ docker version --format 'Engine {{.Server.Version}}'
Engine 29.9.2
$ docker compose version
Docker Compose version v5.6.1
$ df -h / | tail -1
/dev/sda2 443G 179G 246G 43% /
Icecast 是 C 语言编写的单进程服务,资源占用极小(实测运行内存约 20 MB),真正的成本在网络带宽——每路听众都占一份流带宽,128 kbps 的流带 100 个听众就是约 12.8 Mbps 出向带宽。磁盘只要留得下日志即可,246 GB 剩余空间绰绰有余。
1.2 端口与目录规划
Icecast 默认监听 8000 端口。本次规划两个监听端口:8000(主流服务)与 8001(第二监听,用于演示多 listen-socket),分别映射到宿主机 8142 与 8144。部署后用 ss 复核监听就绪(逐行实测输出):
$ ss -ltn | grep -E '8142|8144|8146'
LISTEN 0 4096 0.0.0.0:8142 0.0.0.0:*
LISTEN 0 4096 0.0.0.0:8144 0.0.0.0:*
LISTEN 0 4096 0.0.0.0:8146 0.0.0.0:*
(8146 留给后续中继实例,见《Icecast 常用命令与运维实战》。若你的机器上这些端口被占,任选空闲端口、同步改编排文件即可。)
目录统一放在 /opt/data/quzuo/tmp/icecast/ 下,规划如下(实测目录树):
/opt/data/quzuo/tmp/icecast/
├── build/ # 制品构建材料(Dockerfile + systemd 单元)
│ ├── Dockerfile
│ └── icecast2.service
├── build-client/ # 推流客户端制品构建材料
│ └── Dockerfile
└── compose/ # 编排现场
├── docker-compose.yml
├── etc/icecast.xml # 主配置(挂载为实例 /etc/icecast2/icecast.xml)
├── etc-relay/ # 中继实例配置(运维篇启用)
└── log/ # 日志目录(挂载为实例 /var/log/icecast2)
💡 说明:把配置目录与日志目录以绑定挂载方式落在宿主机,是 Icecast 编排的关键设计——icecast.xml 改完直接热重载即可生效(2.5 支持,运维篇实测),日志则可直接在宿主机用 tail/grep 分析,无需进入实例。
二、制品准备:为什么本地构建
2.1 官方只发布源码包
Icecast 官方(icecast.org / downloads.xiph.org)只发布源代码 tar 包,不提供 Docker 制品。检索 Docker Hub(2026-10-28 实测快照)也只有第三方打包:
infiniteproject/icecast "Icecast 2 for Docker" 4.47M pulls(第三方)
vimagick/icecast "free server software..." 1.47M pulls(第三方)
moul/icecast 1.08M pulls(第三方)
libretime/icecast "based on Debian or Alpine" 125K pulls(第三方)
第三方制品版本滞后且无法确认构建参数,生产环境不建议直接使用。因此本部署采用「官方源码 + 本地构建」路线:以 Ubuntu 24.04 为基底,从 downloads.xiph.org 拉取 libigloo 0.9.5(Icecast 2.5 依赖的基础库)与 icecast-2.5.0 源码编译,配好 systemd 单元,得到一个带完整服务管理能力的制品。
2.2 Dockerfile 逐段解读
build/Dockerfile 全文(实测版本):
FROM ubuntu:24.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
systemd systemd-sysv dbus \
build-essential autoconf automake libtool pkg-config make \
curl ca-certificates xz-utils \
libxml2-dev libxslt1-dev libvorbis-dev libopus-dev libtheora-dev \
libcurl4-openssl-dev libssl-dev librhash-dev \
iproute2 procps net-tools vim-tiny less rsync tar gzip logrotate media-types \
&& rm -rf /var/lib/apt/lists/*
RUN curl -fsSL -o /tmp/libigloo-0.9.5.tar.gz \
https://downloads.xiph.org/releases/igloo/libigloo-0.9.5.tar.gz \
&& mkdir -p /usr/src/libigloo \
&& tar -xzf /tmp/libigloo-0.9.5.tar.gz -C /usr/src/libigloo --strip-components=1 \
&& cd /usr/src/libigloo && ./configure --prefix=/usr \
&& make -j"$(nproc)" && make install && ldconfig \
&& rm -f /tmp/libigloo-0.9.5.tar.gz
RUN curl -fsSL -o /tmp/icecast-2.5.0.tar.gz \
https://downloads.xiph.org/releases/icecast/icecast-2.5.0.tar.gz \
&& mkdir -p /usr/src/icecast \
&& tar -xzf /tmp/icecast-2.5.0.tar.gz -C /usr/src/icecast --strip-components=1 \
&& cd /usr/src/icecast \
&& ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var \
&& make -j"$(nproc)" && make install \
&& mkdir -p /usr/share/icecast \
&& cp -a web admin doc report-db.xml /usr/share/icecast/ \
&& rm -rf /usr/src/icecast /usr/src/libigloo \
&& rm -f /tmp/icecast-2.5.0.tar.gz
RUN useradd -r -s /usr/sbin/nologin -d /var/lib/icecast icecast \
&& mkdir -p /etc/icecast2 /var/log/icecast2 /var/lib/icecast \
&& chown -R icecast:icecast /var/log/icecast2 /var/lib/icecast \
&& chmod 755 /var/log/icecast2
COPY icecast2.service /lib/systemd/system/icecast2.service
RUN ln -sf /lib/systemd/system/icecast2.service /etc/systemd/system/multi-user.target.wants/icecast2.service \
&& systemctl set-default multi-user.target
STOPSIGNAL SIGRTMIN+3
CMD ["/sbin/init"]
要点解读:
- 编译依赖:Icecast 2.5 的 configure 需要 libxml2(配置解析)、libxslt(admin Web 的 XSL 页面)、libvorbis/libopus/libtheora(Ogg 系格式支持)、libcurl(relay 回源与 YP 目录登记)、libssl(TLS)与 librhash;
libigloo是 2.5 新增的基础运行库,必须先装; ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var:让二进制、配置、日志落到 FHS 标准位置,与包管理安装的路径习惯一致;cp -a web admin doc report-db.xml /usr/share/icecast/:Web 状态页、admin 管理页 XSL、内置文档必须随制品分发,否则启动后管理面 404;- 专用用户:创建系统用户
icecast(uid 997),服务以该用户运行,不碰 root; - systemd 单元:实例以
/sbin/init作为入口,Icecast 由 systemd 托管,获得systemctl start/stop/reload与崩溃自动拉起能力(运维篇有崩溃自恢复实测)。
build/icecast2.service 单元文件全文:
[Unit]
Description=Icecast 2.5.0 streaming media server
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=icecast
Group=icecast
ExecStart=/usr/bin/icecast -c /etc/icecast2/icecast.xml
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=3
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
ExecReload=kill -HUP 对应 Icecast 的 SIGHUP 热重载能力;LimitNOFILE=65536 提高文件描述符上限——每路听众都是一条长连接,高并发场景默认 1024 的 ulimit 会成为瓶颈。
2.3 构建实测
在编排目录执行构建(客户端制品同理,build-client/Dockerfile 是 ubuntu:24.04 + ffmpeg + curl 的极简构建,用于扮演推流源):
$ cd /opt/data/quzuo/tmp/icecast/compose
$ docker compose build
实测构建过程关键阶段耗时(BuildKit plain 输出摘录):
#6 [2/7] RUN apt-get update && apt-get install -y ... DONE 421.3s
#7 [3/7] RUN curl ... libigloo-0.9.5.tar.gz ... make DONE 45.5s
#8 [4/7] RUN curl ... icecast-2.5.0.tar.gz ... make DONE 141.8s
#9 [5/7] RUN useradd -r ... icecast ... DONE 0.3s
#10 [6/7] COPY icecast2.service ... DONE 0.0s
#11 [7/7] RUN ln -sf ... systemctl set-default ... DONE 0.1s
#12 exporting to docker.io/library/icecast-2.5.0 DONE 16.0s
首次全量构建约 11 分钟(大头是 apt 装依赖与两段源码编译),产物体积实测:
$ docker image ls icecast-2.5.0 --format '{{.Repository}}:{{.Tag}} {{.Size}}'
icecast-2.5.0:latest 785MB
icecast-client:latest 306MB
三、编排文件详解
compose/docker-compose.yml 全文(实测版本;中继服务块在运维篇引入,此处为基础双服务版):
name: icecast-250-stack
services:
icecast:
build: ../build
image: icecast-2.5.0:latest
container_name: icecast-2.5.0-main
hostname: icecast-node1
privileged: true
cgroup: host
restart: unless-stopped
ports:
- "8142:8000"
- "8144:8001"
volumes:
- ./etc:/etc/icecast2
- ./log:/var/log/icecast2
- /sys/fs/cgroup:/sys/fs/cgroup:rw
tmpfs:
- /run
- /run/lock
networks:
icecast-net:
ipv4_address: 10.89.59.10
client:
image: icecast-client:latest
container_name: icecast-client
hostname: studio-client
command: sleep infinity
networks:
icecast-net:
ipv4_address: 10.89.59.20
networks:
icecast-net:
name: icecast-250-net
driver: bridge
ipam:
config:
- subnet: 10.89.59.0/24
逐段解读:
privileged: true+cgroup: host+tmpfs: /run,/run/lock:实例入口是 systemd(/sbin/init),这三项是让 systemd 在实例内正常工作的标准三件套;hostname: icecast-node1:固定实例主机名,Icecast 启动日志与 relay 互联都引用它;ports:8142 对 8000(主服务口,推流/收听/管理全走这里)、8144 对 8001(第二监听口,演示多 listen-socket);volumes:./etc对/etc/icecast2(配置可宿主机直改)、./log对/var/log/icecast2(日志宿主机直读);- 固定 IP:
icecast-net子网 10.89.59.0/24,主服务固定 10.89.59.10、推流客户端固定 10.89.59.20——relay 中继与访问日志分析都需要稳定地址; client服务:扮演「推流源客户端」角色(ffmpeg 推流),sleep infinity保持常驻,随时 exec 进去操作。
配套主配置 compose/etc/icecast.xml(本篇使用的初始版本,逐段详解见《Icecast 配置参数详解》):
<?xml version="1.0" encoding="UTF-8"?>
<icecast>
<location>CN</location>
<admin>admin@icecast.local</admin>
<hostname>icecast.local</hostname>
<limits>
<clients>100</clients>
<sources>2</sources>
<queue-size>524288</queue-size>
<client-timeout>30</client-timeout>
<header-timeout>15</header-timeout>
<source-timeout>10</source-timeout>
<burst-size>65535</burst-size>
</limits>
<authentication>
<source-password>q1w2e3r4</source-password>
<relay-password>q1w2e3r4</relay-password>
<admin-user>admin</admin-user>
<admin-password>q1w2e3r4</admin-password>
</authentication>
<listen-socket>
<port>8000</port>
</listen-socket>
<listen-socket>
<port>8001</port>
</listen-socket>
<paths>
<logdir>/var/log/icecast2</logdir>
<webroot>/usr/share/icecast/web</webroot>
<adminroot>/usr/share/icecast/admin</adminroot>
<alias source="/" destination="/status.xsl"/>
</paths>
<logging>
<accesslog>access.log</accesslog>
<errorlog>error.log</errorlog>
<loglevel>4</loglevel>
</logging>
</icecast>
⚠️ 安全提示:本篇所有密码统一为
q1w2e3r4仅为实验室演示。生产环境务必替换为高强度独立密码,且 icecast.xml 含明文密码,文件权限应收紧到属主可读(2.5 启动时检测到全局可读会打EROR util/util_test_file_modes ... world read permission警告,运维篇有实测)。
四、启动与初始化验证
4.1 启动
$ cd /opt/data/quzuo/tmp/icecast/compose
$ docker compose up -d
回显(逐行实测):
Network icecast-250-net Created
Container icecast-2.5.0-main Created
Container icecast-client Created
Container icecast-client Started
Container icecast-2.5.0-main Started
docker compose ps 复核:
NAME IMAGE COMMAND SERVICE STATUS PORTS
icecast-2.5.0-main icecast-2.5.0:latest "/sbin/init" icecast Up 9 seconds 0.0.0.0:8142->8000/tcp, [::]:8142->8000/tcp, 0.0.0.0:8144->8001/tcp, [::]:8144->8001/tcp
icecast-client icecast-client:latest "sleep infinity" client Up 9 seconds
4.2 进程与初始化日志
实例内 Icecast 由 systemd 托管,确认服务状态:
$ systemctl status icecast2 --no-pager
● icecast2.service - Icecast 2.5.0 streaming media server
Loaded: loaded (/usr/lib/systemd/system/icecast2.service; enabled; preset: enabled)
Active: active (running) since Wed 2026-10-28 13:56:44 UTC; 9s ago
Main PID: 74 (icecast)
Tasks: 10 (limit: 3172)
Memory: 4.4M (peak: 5.0M)
初始化日志(/var/log/icecast2/error.log,宿主机直接读 ./log/error.log,逐行实测):
[2026-10-28 13:56:44] WARN CONFIG/_parse_root Warning, no PRNG seed configured, falling back to libigloo defaults.
[2026-10-28 13:56:44] INFO stats/_stats_thread stats thread started
[2026-10-28 13:56:44] INFO fserve/fserve_initialize file serving started
[2026-10-28 13:56:44] INFO main/main Icecast 2.5.0 server started
[2026-10-28 13:56:44] INFO main/main Server's PID is 74
[2026-10-28 13:56:44] INFO main/__log_system_name Running on icecast-node1; OS: Linux 7.0.0-38-generic, icecast-node1, #38~24.04.4-Ubuntu SMP PREEMPT_DYNAMIC Mon Sep 14 16:37:11 UTC 2, x86_64; Address Bits: 64
[2026-10-28 13:56:44] INFO main/__log_system_name From configuration: Our hostname is "icecast.local", located "CN", with admin contact "admin@icecast.local"
[2026-10-28 13:56:44] INFO connection/get_tls_certificate No TLS capability on any configured ports
[2026-10-28 13:56:44] INFO yp/yp_update_thread YP update thread started
读法:版本横幅与 PID、运行环境(内核/架构)、从配置读到的 hostname/location/admin 三件套、TLS 能力探测(本配置未开 TLS)、YP 目录线程就绪。首行 no PRNG seed configured 是 2.5 的新检查项——应在 security 段补 <prng-seed type="profile">linux</prng-seed>,改法与验证见《Icecast 配置参数详解》。
五、推流链路实测
Icecast 本身不产生内容,需要源客户端推流。本章用客户端实例里的 ffmpeg 造一段测试音频并推到 /stream 挂载点。
5.1 生成测试音频
用 ffmpeg 的 lavfi 虚拟声源生成一段 440 Hz + 554 Hz 双声道正弦音(20 秒、128 kbps MP3、带 ID3 元数据):
$ ffmpeg -hide_banner -y -f lavfi -i 'sine=frequency=440:duration=20' \
-f lavfi -i 'sine=frequency=554:duration=20' \
-filter_complex '[0:a][1:a]amerge=inputs=2[a]' -map '[a]' \
-c:a libmp3lame -b:a 128k \
-metadata title='Quzuo Demo Tone 440+554Hz' -metadata artist='Icecast Lab' \
/tmp/test-tone.mp3
回显(尾部摘录):
size= 314kB time=00:00:19.98 bitrate= 128.5kbits/s speed= 103x
$ ls -l /tmp/test-tone.mp3
-rw-r--r-- 1 root root 321096 Oct 28 13:57 /tmp/test-tone.mp3
5.2 ffmpeg 推流
以 -re(按真实速率读文件)+ -stream_loop -1(无限循环)把测试音推到 /stream,-ice_* 系列参数填写电台名/简介/流派:
$ ffmpeg -hide_banner -nostats -re -stream_loop -1 -i /tmp/test-tone.mp3 \
-c:a copy -content_type audio/mpeg -f mp3 \
-ice_name 'Quzuo Demo Radio' -ice_description 'Icecast 2.5.0 demo mount' \
-ice_genre 'Test' -ice_public 0 \
icecast://source:q1w2e3r4@icecast-node1:8000/stream
推流端日志(逐行实测,后台持续运行):
Input #0, mp3, from '/tmp/test-tone.mp3':
Duration: 00:00:20.04, start: 0.025057, bitrate: 128 kb/s
Output #0, mp3, to 'icecast://source:q1w2e3r4@icecast-node1:8000/stream':
Metadata:
TIT2 : Quzuo Demo Tone 440+554Hz
TPE1 : Icecast Lab
Stream #0:0: Audio: mp3, 44100 Hz, stereo, fltp, 128 kb/s
Stream mapping:
Stream #0:0 -> #0:0 (copy)
服务端 error.log 同步记录源接入(逐行实测):
[2026-10-28 13:57:07] INFO connection-handle/_handle_source_request Source logging in at mountpoint "/stream" using "PUT" from 10.89.59.20 as role legacy-global-source with acl legacy-global-source
[2026-10-28 13:57:07] INFO source/source_main listener count on /stream now 0
💡 技术拓展:Icecast 收推流有两种协议形态——
形态 说明 典型客户端 HTTP PUT(Icecast 2.4+)标准 HTTP 语义,走基础设施(CDN/反代)友好,上例 ffmpeg 即此形态(日志里的 using "PUT")ffmpeg、Liquidsoap SOURCE方法(Icecast 1 沿袭)Icecast 私有方法,老牌推流软件兼容性最好 ices2、ezstream、Mixxx SHOUTcast v1 兼容模式 配置 shoutcast-compat后接收 SHOUTcast 源老旧 DJ 软件 对听众一侧,Icecast 出流是带
icy-*扩展头的 HTTP 顺序流——「Icecast 协议」本质是 HTTP GET 长连接 + ICY 元数据插播;而「SHOUTcast 协议」是 SHOUTcast 私有的推/拉约定。Icecast 服务器对收听侧兼容 ICY 语义,所以几乎所有播放器都能直接播放。
六、拉流验证(icy-* 响应头)
听众侧用 curl 模拟播放器拉流,重点看响应头里的 icy-* 字段(这就是播放器显示电台名/歌曲名的数据来源):
$ curl -sv --max-time 4 http://localhost:8142/stream -o /dev/null
回显(逐行实测,摘录关键头):
> GET /stream HTTP/1.1
> Host: localhost:8142
> User-Agent: curl/8.5.0
>
< HTTP/1.1 200 OK
< Server: Icecast 2.5.0
< Content-Type: audio/mpeg
< Cache-Control: no-cache, no-store
< icy-description:Icecast 2.5.0 demo mount
< icy-genre:Test
< icy-name:Quzuo Demo Radio
< icy-pub:0
< icy-metadata:1
<
* Operation timed out after 4001 milliseconds with 124600 bytes received
逐项核对:icy-name/icy-description/icy-genre 正是推流时 -ice_* 写入的值;icy-metadata:1 表示流内支持插播元数据(更新当前曲目见运维篇);4 秒收到 124600 字节 ≈ 64 KB burst 预缓冲 + 3 秒多的实时流(128 kbps ≈ 16 KB/s),说明 burst 机制工作正常(burst-size 详解与对照测量见《Icecast 配置参数详解》)。
再验证第二监听口(8144 → 8001)与别名(/ 跳转到状态页):
$ curl -s -o /dev/null -w '%{http_code}\n' --max-time 2 http://localhost:8144/stream
200
$ curl -s -o /dev/null -w '%{http_code} %{redirect_url}\n' http://localhost:8142/
302 http://localhost:8142/status.xsl
七、管理面验证与听众计数
7.1 Web 状态页与 Dashboard
浏览器(或 curl)打开 http://localhost:8142/ 即状态页(公开页,无需登录);http://localhost:8142/admin/ 是管理面,HTTP Basic 认证,用户名 admin、密码 q1w2e3r4(即 icecast.xml 的 admin-user/admin-password)。curl 验证页面标题(逐行实测):
$ curl -s http://localhost:8142/status.xsl | grep -oE '<title>[^<]+</title>'
<title>Status — Icecast Server</title>
$ curl -s -u admin:q1w2e3r4 http://localhost:8142/admin/ | grep -oE '<title>[^<]+</title>'
<title>Dashboard — Icecast Admin</title>
7.2 /admin/stats 接口
管理面的数据源是 /admin/stats(XML 输出,程序化运维都靠它)。当前全局与 /stream 挂载的关键字段(逐行实测摘录):
$ curl -s -u admin:q1w2e3r4 http://localhost:8142/admin/stats
<icestats>
<server_id>Icecast 2.5.0</server_id>
<server_start>Wed, 28 Oct 2026 13:56:44 +0000</server_start>
<host>icecast.local</host>
<location>CN</location>
<sources>1</sources>
<clients>1</clients>
<listeners>0</listeners>
<source mount="/stream">
<server_name>Quzuo Demo Radio</server_name>
<server_type>audio/mpeg</server_type>
<listenurl>http://localhost:8142/stream</listenurl>
<user_agent>Lavf/60.16.100</user_agent>
<source_ip>10.89.59.20</source_ip>
<stream_start>Wed, 28 Oct 2026 13:57:07 +0000</stream_start>
<listeners>0</listeners>
<listener_peak>3</listener_peak>
<max_listeners>unlimited</max_listeners>
<total_bytes_read>58412793</total_bytes_read>
<total_bytes_sent>777187</total_bytes_sent>
</source>
</icestats>
sources=1 确认一路源在线;user_agent=Lavf/60.16.100 是 ffmpeg 的推流标识;source_ip=10.89.59.20 正是客户端实例的固定 IP。
7.3 听众计数实测
起 3 个 curl 模拟 3 路并发听众,再看 stats 计数变化:
$ for i in 1 2 3; do curl -s http://localhost:8142/stream -o /dev/null & done
$ sleep 3
$ curl -s -u admin:q1w2e3r4 http://localhost:8142/admin/stats | grep -oE '<listeners>[0-9]+</listeners>|<listener_peak>[0-9]+</listener_peak>'
<listeners>3</listeners>
<listener_peak>3</listener_peak>
断开全部听众后复查:
$ pkill -f 'curl -s http://localhost:8142/stream'
$ sleep 3
$ curl -s -u admin:q1w2e3r4 http://localhost:8142/admin/stats | grep -oE '<listeners>[0-9]+</listeners>|<listener_peak>[0-9]+</listener_peak>'
<listeners>0</listeners>
<listener_peak>3</listener_peak>
listeners 回落到 0、listener_peak 保持历史峰值 3——peak 值用于容量复盘,重启源后清零。至此「推流→分发→计数」全链路验证完毕。
八、排障实录
以下四则故障均为本次实测中真实触发并记录的,按「现象→回显→定位→处置」给出。
1. 推流密码错误(401)
$ ffmpeg ... icecast://source:wrongpass@icecast-node1:8000/badpass
[http @ 0x5ed19a094e00] HTTP error 401 Authentication Required
[out#0/mp3 @ 0x5ed19a091840] Error opening output icecast://source:wrongpass@icecast-node1:8000/badpass: Server returned 401 Unauthorized (authorization failed)
定位:401 说明 TCP/HTTP 层通,纯粹是认证失败。核对 icecast.xml 的 source-password 与推流 URL 中的密码段(source:密码@主机)。注意密码含 @、:、URL 保留字符时需转义。
2. 收听不存在的挂载点(404)
$ curl -s -o /dev/null -w '%{http_code}\n' http://localhost:8142/nosuchmount
404
$ curl -s http://localhost:8142/nosuchmount
<?xml version="1.0"?>
<report ...><incident><state definition="18c32b43-..."><text>The file you requested could not be found</text></state></incident></report>
定位:2.5 的 404 返回 report XML 而非 HTML。先 curl /admin/listmounts 确认在线挂载清单——挂载点只有在源推流在线时才存在(除非配置了静态文件回退)。
3. 源数量超限(503)
本篇配置 limits/sources=2。当 /stream 与 /live 两路源在线时再推第三路:
$ ffmpeg ... icecast://source:q1w2e3r4@icecast-node1:8000/extra
Error opening output files: Server returned 5XX Server Error reply
服务端 error.log 同步记录:
[2026-10-28 13:58:11] WARN connection/connection_complete_source Request to add source when maximum source limit reached 2
定位:5XX + 服务端 WARN 直指 sources 上限。处置:调高 limits/sources 或改用多实例分担;access.log 中对应记录为 "PUT /extra HTTP/1.1" 503。
4. 端口被占用
调整编排换端口前,先用 ss -ltn 确认目标端口空闲。占用时启动会直接失败,实测在已占用端口上起服务的报错:
$ python3 -c "import http.server,socketserver;socketserver.TCPServer(('',8142),...).serve_forever()"
Traceback (most recent call last):
...
OSError: [Errno 98] Address already in use
处置:ss -ltnp 找到占用进程,或改用本文端口规划中的空闲端口(8146 等)。
九、小结
本篇完成了 Icecast 2.5.0 的 0→1:本地构建 systemd 制品(约 11 分钟、785 MB)→ 双服务编排(主服务 + 推流客户端)→ ffmpeg lavfi 造流推 /stream → curl 核对 icy-* 响应头 → admin stats 与 3 路听众计数闭环,并记录了 401/404/503/端口冲突四则排障。接下来:icecast.xml 每个参数的含义与改值验证见《Icecast 配置参数详解》;信号管理、admin XSL 接口批量操作、relay 主从中继、日志分析与备份升级见《Icecast 常用命令与运维实战》。