news 2026/9/25 23:28:14

ZLMediaKit离线Docker部署全流程:从镜像导出到内网运行

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ZLMediaKit离线Docker部署全流程:从镜像导出到内网运行

简介:面向需要在离线或内网环境部署ZLMediaKit流媒体服务的运维人员与开发者,这份资源提供了一套完整的Docker离线安装方案。资源包包含2个文件,分别为Docker镜像压缩包与一键安装脚本,镜像tar包用于导入本地Docker环境,脚本则自动完成镜像加载与容器启动等操作,整体大小约为208.73MB,可有效避开外网拉取镜像的不便。目前已有375人学习下载。借助该资源,读者可减少手动配置环节,快速获得可运行的ZLMediaKit服务,尤其适合生产环境中无外网、需批量交付或快速验证的场景。相比在线安装,离线包方式速度更稳、依赖可控,配套脚本也便于二次定制,是一份实用性与可操作性兼备的部署工具。

1. zlm docker 离线安装:把镜像和运行时分开搬,内网就能跑

现场服务器连不了外网,领导又只给半天时间,要你把手上的流媒体服务部署上,这时候最怕的就是去源码编译 ZLMediaKit。zlm docker 离线安装的思路其实很简单:在能联网的机器上把 zlm 镜像导出成 tar,再把 tar 运到内网机器上 load,同时给内网机器准备一个离线可用的 Docker 运行时。这里最反直觉的一点是,离线安装的难点不在 zlm 本身,而在镜像怎么选、Docker 运行时怎么补。你不需要 yum 源,也不需要外网,只需要遵循一条原则:镜像从在线机带进去,运行时从安装包带进去。适合的场景包括机房隔离环境、客户现场、以及任何没有 Docker Hub 访问权限的产线。

2. 联网机准备 zlm 镜像:从 pull 到 save,选对 tag 和架构

离线部署的第一步不是在目标机上装 Docker,而是先在联网机上把镜像准备好。这里说的联网机可以是你的笔记本电脑,也可以是一台临时跳板机。目标只有一个:生成一个完整、可传输、能直接 load 的镜像 tar 文件。大多数人在这步翻车,不是因为不会用 docker,而是随手docker pull zlmediakit/zlmediakit:latest就完事,没考虑目标机的 CPU 架构,也没确认 tag 是否适合生产环境。

2.1 选镜像 tag:稳定版优先,不要迷信 latest

ZLMediaKit 官方镜像在 Docker Hub 上的仓库名常见写法是zlmediakit/zlmediakit,tag 有 latest、master 和若干 release 版本。对于离线部署,我的建议是选带版本号的 release 标签,而不是 latest。latest 通常指向开发分支,可能包含尚未充分验证的改动;离线环境没有外网去临时拉修复镜像,一旦踩坑,你要重新走一遍下载、导出、传输的完整流程,代价非常高。

选 tag 之前,先确认内网服务器的 CPU 架构。在目标机上执行uname -m,输出 x86_64 对应 amd64 镜像,输出 aarch64 对应 arm64 镜像。如果你是 Intel 下载机配 ARM 目标机,就需要在拉取时显式指定平台。这里有个容易被忽略的细节:docker pull默认拉取当前机器的架构,不会自动帮你选择目标机的架构。离线部署里真正要回答的“哪个版本最兼容”,第一步就是先定架构,再定版本,而不是先拉 latest 再说。

2.2 拉取镜像:受 Docker Hub 速度影响,先查空间再动手

下载机上执行下面的命令,实际 tag 以你在 Docker Hub 上确认到的 release 标签为准。

docker pull zlmediakit/zlmediakit:release

这个命令会拉取指定 tag 的镜像,并在本地按层存储。pull 过程中会显示 Pulling fs layer、Downloading、Extracting 等状态。一个完整的 zlm 镜像通常有大几百兆,取决于是否包含 ffmpeg、x264 等运行库。下载前建议先用df -h /var/lib/docker确认空间充足,否则可能到一半报磁盘满。

Docker Hub 在网络环境不稳定时下载速度很慢,这是常态。有的团队会在这台下载机上配置 registry-mirror 做加速,但请记住:这是在线加速手段,不是离线部署方案。离线安装的核心是“只在联网机上拉一次,把结果带走”,只要最终 tar 文件完整,中途慢一点不影响目标机。

2.3 导出镜像:docker save 是把镜像完整打包的唯一正路

导出镜像用docker save,不是docker export。两者的区别是:save保留镜像的分层、tag 和构建历史,load 回去后仍然是完整镜像;export导出的是容器的文件系统,不包含镜像元数据,load 后无法按原 tag 直接运行。生产环境离线传输,一律用 save。

docker save -o zlm-release.tar zlmediakit/zlmediakit:release

-o指定输出文件名,后面接仓库名和 tag。如果想减小传输体积,最常用的做法是导出后立即 gzip 压缩:

docker save zlmediakit/zlmediakit:release | gzip > zlm-release.tar.gz

load 时 Docker 会自动识别 gzip 压缩包,不需要手动解压。压缩后的文件通常比原始 tar 小一半,适合用 U 盘或内网 scp 拷贝。镜像 tar 内部已经包含所有依赖层,目标机 load 时不需要访问任何仓库,这就是离线安装能成立的原理。

2.4 多个 tag 或镜像一并导出

生产环境里你可能会同时保留两个 tag,或者在镜像基础上追加了调试工具、改过配置,需要打包多个镜像。逐个 save 太啰嗦,可以一条命令解决:

docker save -o all-zlm.tar \ zlmediakit/zlmediakit:release \ zlmediakit/zlmediakit:latest

也可以借助 docker images 过滤出所有相关仓库:

docker images --format '{{.Repository}}:{{.Tag}}' | grep zlmediakit | \ xargs docker save -o all-zlm.tar

--format让输出只保留仓库和 tag,再通过管道交给 docker save,避免手敲漏 tag。导出完成后,建议用压缩包完整校验代替肉眼确认:

tar -tzf zlm-release.tar.gz > /dev/null && echo "tar OK"

如果 tar 损坏,会立即报错。另外可以用docker image inspect确认镜像架构,避免后面在 ARM 机器上跑 x86 镜像。

3. 无网服务器装 Docker:CentOS 7 的静态二进制包与 rpm 两条路

目标机没有外网,就不能简单执行yum install docker,因为 yum 源默认指向公网。这里需要先明确你要装的 Docker 运行时包含哪几部分:docker daemon、docker CLI、containerd、runc。官方提供的离线安装路径有两条:静态二进制包和 rpm 离线源。我的建议是能拿到官方 tgz 就用静态包,依赖最少;如果你公司已经有离线软件仓库,rpm 包路线更贴合既有运维流程。

3.1 静态二进制包:免依赖、可控性最高

静态包是一个 tgz,解压后包含 docker、dockerd、containerd、runc、docker-init 等文件。下载时注意版本号要和目标机内核兼容,CentOS 7 使用 20.10.x 是稳妥选择。

tar -xzf docker-20.10.24.tgz cp docker/* /usr/bin/

解压后的docker/目录内容直接放到/usr/bin,这样 systemd 服务文件里的 ExecStart 路径可以保持一致。接下来创建 docker.service 文件:

cat > /etc/systemd/system/docker.service <<'EOF' [Unit] Description=Docker Daemon After=network-online.target Wants=network-online.target [Service] Type=notify ExecStart=/usr/bin/dockerd ExecReload=/bin/kill -s HUP $MAINPID Restart=always RestartSec=5 LimitNOFILE=1048576 [Install] WantedBy=multi-user.target EOF systemctl daemon-reload systemctl enable --now docker

说明:Type=notify是 dockerd 的标准通知机制,systemd 会等 daemon 真正 ready 再继续;Restart=always保证进程被意外 kill 后自动拉起。静态包方式不依赖 rpm,也不存在依赖包缺失的连锁问题。但你仍然要保证/usr/bin在 PATH 中,第二步的 cp 命令不会自动赋予执行权限,检查一下文件权限即可。

装完后立刻验证:

docker version --format '{{.Server.Version}}'

如果输出了 Server 版本,daemon 正常。如果只有 Client 版本,说明 dockerd 没起来,需要看 journalctl 或 /var/log/messages。这一步一定要做,很多离线部署翻车都发生在 Docker 还没起来就急着 load 镜像。

3.2 rpm 包离线源:在联网机用 yumdownloader 抓全依赖

如果公司的离线仓库已经管理了 rpm 包,rpm 方式更符合现有流程。先在联网 CentOS 7 机器上准备一个临时目录:

mkdir ~/docker-rpm && cd ~/docker-rpm yum install -y yum-utils yumdownloader --resolve docker-ce docker-ce-cli containerd.io

yumdownloader --resolve会把主包和所有依赖包一起下载,包括 container-selinux、iptables 等。这一步可能会下载几十个 rpm,需要全部拷到内网机器。

在内网机器上创建本地仓库:

mkdir -p /opt/docker-rpm cp *.rpm /opt/docker-rpm/ yum install -y createrepo createrepo /opt/docker-rpm cat > /etc/yum.repos.d/docker-local.repo <<'EOF' [docker-local] name=docker-local baseurl=file:///opt/docker-rpm enabled=1 gpgcheck=0 EOF yum clean all yum install -y docker-ce docker-ce-cli containerd.io systemctl enable --now docker

rpm 方式的优点是安装路径和 systemd 服务统一由包管理处理,卸载也干净。缺点是依赖解析比较烦,如果 yumdownloader 阶段换过源,或者目标机内核版本较老,container-selinux 可能装不上。遇到依赖冲突,优先看 yum 输出的Needed项,把对应的 rpm 补进目录后重新 createrepo。

3.3 离线环境里 daemon.json 要留意的三个参数

Docker daemon 启动后,即使不联网也能正常运行,但离线环境里默认配置有一些点值得提前调整。比如默认>mkdir -p /data/docker cat > /etc/docker/daemon.json <<'EOF' { "data-root": "/data/docker", "storage-driver": "overlay2", "log-level": "warn" } EOF systemctl restart docker

storage-driver用 overlay2,CentOS 7 内核一般原生支持;log-level设成 warn 可以减少日志占用。注意,改>docker load -i zlm-release.tar.gz docker images | grep zlmediakit

-i后面既可以接未压缩的.tar,也可以接 gzip 压缩包。load 会逐层解压写入 Docker 的>docker tag <IMAGE ID> zlmediakit/zlmediakit:release

load 的时间受磁盘速度影响,一个 1G 镜像通常需要一两分钟。如果 tar 文件在复制过程中损坏,load 会报layer does not exist或mount has been changed,这不是 tar 格式错误,而是数据不完整,重新拷贝一次再 load 即可。

4.2 启动最小容器:默认配置可以直接跑

ZLMediaKit 默认监听三个主要端口:RTSP 的 554,RTMP 的 1935,HTTP/HTTP-FLV 的 8080。不修改配置的情况下,可以这样启动:

docker run -d --name zlm --restart unless-stopped \ -p 1935:1935 -p 554:554 -p 8080:8080 \ zlmediakit/zlmediakit:release

-d后台运行,--name zlm便于后续 logs 查看,--restart unless-stopped让容器在机器重启后自动拉起,这个参数在无人值守的离线环境里几乎是必备项。-p 外部端口:容器端口把宿主机端口映射进容器。如果不想占用 554 这种特权端口,可以改成-p 8554:554,播放时访问 8554 即可。

启动后立刻确认端口在监听:

ss -lnt | grep -E '1935|554|8080'

如果没有宿主机侧监听,说明映射失败,多半是端口被占或 docker-proxy 没起来,可以进入第 5 章排查。

4.3 需要改配置时:先 find 定位配置文件,再挂载出来

默认配置适合测试,生产环境一般要改 HTTP 端口、secret、流媒体鉴权。zlm 的配置是一个 config.ini,不要凭记忆猜容器内路径,先查真实路径:

docker exec zlm sh -c 'find / -name "config.ini" 2>/dev/null'

这一步会输出实际路径,不同镜像版本可能不同,常见位置在 /opt/media/conf 下。确认后把它拷贝到宿主机:

mkdir -p /opt/zlmediakit/conf docker cp zlm:/opt/media/conf/config.ini /opt/zlmediakit/conf/config.ini vim /opt/zlmediakit/conf/config.ini

改完后删掉旧容器,用挂载方式重新启动:

docker stop zlm && docker rm zlm docker run -d --name zlm --restart unless-stopped \ -v /opt/zlmediakit/conf:/opt/media/conf \ -p 1935:1935 -p 554:554 -p 8080:8080 \ zlmediakit/zlmediakit:release

注意-v右边的路径必须与 find 出来的真实路径一致。如果挂载后配置文件没生效,先看 docker logs 里有没有 permission denied,这通常是宿主目录权限问题。

4.4 用 docker compose 固定整套启动参数

离线环境里手敲 docker run 容易漏参数。如果你已经装了 docker compose 插件,可以用一个 compose 文件固定整套配置:

services: zlm: image: zlmediakit/zlmediakit:release container_name: zlm restart: unless-stopped ports: - "1935:1935" - "554:554" - "8080:8080" volumes: - /opt/zlmediakit/conf:/opt/media/conf

在 compose 文件所在目录执行:

docker compose up -d

compose 会优先使用本地镜像,离线环境不会主动去仓库拉取。如果本地没有镜像,它会报拉取失败,这正好提醒你回头做 load。compose 的好处是把启动参数写成代码,团队维护时不容易各写一套 docker run。没有 compose 插件时,docker run 方案完全够用。

5. 离线部署 zlm 的常见问题排查:五条真实踩坑记录

离线安装和在线安装最大的区别是:出问题时往往没有外网去搜答案,只能靠日志和系统状态逆推。下面五条是我在 CentOS 7 离线环境里实际见过的坑,每一条按现象、原因、解决三步写。

5.1 镜像架构不匹配:Exec format error

现象:docker load 一切正常,docker run 后容器秒退,docker logs zlm只有一句exec user process caused: exec format error。

原因:下载机是 x86_64,目标服务器是 aarch64,而你 pull 到的镜像是 amd64 架构。docker pull 默认拉取当前机器的架构,不会自动跨平台选择目标机架构。

解决:在下载机拉镜像前明确指定平台:

docker manifest inspect zlmediakit/zlmediakit:release docker pull --platform linux/arm64 zlmediakit/zlmediakit:release

docker manifest inspect会列出该镜像支持的架构。导出前再用docker image inspect确认 Architecture 字段。如果镜像本身没有 arm64 版本,那就只能换源码编译,或找适配目标架构的镜像。这个问题的本质是:离线镜像必须与目标机架构强绑定。

5.2 docker load 报 no space left on device

现象:内网机器执行docker load -i zlm.tar.gz,解压到一半报no space left on device,而 tar 文件本身只有几百 MB。

原因:load 会把镜像分层解压到 Docker 的>docker system df docker system prune -a

清理后仍然不足,就把>firewall-cmd --permanent --add-port=1935/tcp firewall-cmd --permanent --add-port=554/tcp firewall-cmd --permanent --add-port=8080/tcp firewall-cmd --reload

如果用云主机,还要到云控制台的安全组里放通这些入方向端口。这个坑最容易在最后验证阶段暴露,所以我会在部署完成后,坚持做一次端到端推流验证,而不是只看 docker ps。

5.5 端口冲突:旧容器没删干净,新容器起不来

现象:docker run启动 zlm 时提示bind: address already in use,但ss -lntp看到的占用者是一个 docker-proxy 进程,而不是应用进程。

原因:上一次部署留下的旧容器还处于运行或退出状态,它的端口映射没有释放;或者另一个服务占用了 8080 / 1935。

解决:先查所有容器和端口占用:

docker ps -a ss -lntp | grep 1935

确认占用者是无用容器后,删除再启动:

docker stop zlm && docker rm zlm docker run -d --name zlm --restart unless-stopped \ -p 1935:1935 -p 554:554 -p 8080:8080 \ zlmediakit/zlmediakit:release

如果端口被其他系统进程占用,比如 Apache 占了 8080,就直接换宿主机侧映射-p 8081:8080,不必改容器内配置。这个坑看似低级,但在离线现场最容易遇到,因为往往多个服务挤在同一台机器上。

6. 验证 zlm 容器能出流:ffmpeg 推流一分钟够用

部署完成不等于交付。我见过不止一次docker ps显示运行中,结果实际拉流时才发现流地址配错了。离线环境没有在线检测服务可依赖,最可靠的方式是自己推一路流,再亲自拉回来。

在能访问 zlm 服务器的机器上准备一个 mp4 测试文件,执行推流:

ffmpeg -re -stream_loop -1 -i test.mp4 -c copy -f flv rtmp://<zlm-ip>:1935/live/test

-re按文件真实时间率推流,-stream_loop -1让视频循环,避免推流几秒就结束。然后另开终端用 ffprobe 验证:

ffprobe -v error -show_entries stream=codec_name,width,height -of json rtmp://<zlm-ip>:1935/live/test

如果输出了编码、宽高,说明 zlm 的 RTMP 接入和转发链路正常。想验证 HTTP-FLV,把播放地址改成:

ffplay http://<zlm-ip>:8080/live/test.flv

同时观察 zlm 日志:

docker logs -f zlm | grep -E 'play|publish'

看到 publish 和 play 两条日志,一次完整的推拉流闭环就通了。如果 ffprobe 没输出,按第 5 章的端口排查从头过一遍,不要急着改配置。

我自己的习惯是部署完后不急着交工,先推流一分钟再离开。有一次我跳过这步,结果客户现场拉流时才发现生产环境安全组没放行 RTSP 端口,远程折腾了半小时。从那以后,离线部署 zlm 的验证命令就固定成了三条:推流、拉流、看日志。这套流程也适用于以后升级镜像版本,至少能确认新镜像没有把端口或协议弄丢。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/25 23:27:43

魔兽世界宏命令源码实战:用Python解析与批量生成可靠宏

简介&#xff1a;一份面向魔兽世界玩家的宏命令指南项目源码&#xff0c;聚焦宏命令从基础批处理到 LUA 脚本的完整学习路径&#xff0c;旨在解决游戏中重复操作效率低下、技能衔接不够流畅等问题&#xff0c;适合新手入门及有进阶需求的玩家。源码以 HTML 主文档为核心&#x…

作者头像 李华
网站建设 2026/9/25 23:27:16

银河麒麟V10网卡驱动编译加载全指南:e1000e与rtl8125适配实战

简介&#xff1a;本资源是专为银河麒麟V10操作系统适配的e1000e与RTL8125网卡驱动源码包&#xff0c;面向国产化信创环境下的Linux内核开发者、系统集成工程师及运维人员&#xff0c;解决Intel和Realtek主流千兆网卡在麒麟V10上因内核版本差异导致的编译失败问题。压缩包共56个…

作者头像 李华
网站建设 2026/9/25 23:22:34

本科毕设首选:基于Hugging Face的中文文本摘要实战指南

简介&#xff1a;本资源是一份面向本科生的深度学习文本摘要实践项目&#xff0c;聚焦自然语言处理中的自动摘要任务&#xff0c;以Transformer模型为核心技术方案&#xff0c;完整覆盖数据预处理、模型构建、训练调优与评估全流程&#xff0c;特别适合作为本科毕业设计选题与实…

作者头像 李华
网站建设 2026/9/25 23:17:14

搭建Agent系统实战:从0到1把大模型变成能干活的手

简介&#xff1a;一份面向软件开发者的Agent系统可运行源码包&#xff0c;适合具备Python基础、希望从零搭建或升级Agent应用的读者。资源完整呈现从离线笔记到联机版Agent的升级实践&#xff0c;涵盖Researcher、Editor、Note Taker三个角色的分工协作&#xff0c;以及搜索工具…

作者头像 李华
网站建设 2026/9/25 23:14:43

企业AI落地全流程指南:场景评估、RAG与Agent实践

简介&#xff1a;科易网作为国家级企业服务平台&#xff0c;推出一份AI驱动创新赋能企业数智化转型的专题文档&#xff0c;面向受科技信息碎片化、技术资源匹配难、客户服务响应慢、人才培养周期长等困扰的企业管理者与科技创新服务从业者。文档系统梳理了AI技术图谱、AI技术情…

作者头像 李华