资讯动态

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

发布时间:2026/9/25 23:28:30 来源:尧图企业网站定制
简介面向需要在离线或内网环境部署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稳定版优先不要迷信 latestZLMediaKit 官方镜像在 Docker Hub 上的仓库名常见写法是zlmediakit/zlmediakittag 有 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.gzload 时 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. 无网服务器装 DockerCentOS 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] DescriptionDocker Daemon Afternetwork-online.target Wantsnetwork-online.target [Service] Typenotify ExecStart/usr/bin/dockerd ExecReload/bin/kill -s HUP $MAINPID Restartalways RestartSec5 LimitNOFILE1048576 [Install] WantedBymulti-user.target EOF systemctl daemon-reload systemctl enable --now docker说明Typenotify是 dockerd 的标准通知机制systemd 会等 daemon 真正 ready 再继续Restartalways保证进程被意外 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.ioyumdownloader --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] namedocker-local baseurlfile:///opt/docker-rpm enabled1 gpgcheck0 EOF yum clean all yum install -y docker-ce docker-ce-cli containerd.io systemctl enable --now dockerrpm 方式的优点是安装路径和 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 dockerstorage-driver用 overlay2CentOS 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:releaseload 的时间受磁盘速度影响一个 1G 镜像通常需要一两分钟。如果 tar 文件在复制过程中损坏load 会报layer does not exist或mount has been changed这不是 tar 格式错误而是数据不完整重新拷贝一次再 load 即可。4.2 启动最小容器默认配置可以直接跑ZLMediaKit 默认监听三个主要端口RTSP 的 554RTMP 的 1935HTTP/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 -dcompose 会优先使用本地镜像离线环境不会主动去仓库拉取。如果本地没有镜像它会报拉取失败这正好提醒你回头做 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:releasedocker 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-port1935/tcp firewall-cmd --permanent --add-port554/tcp firewall-cmd --permanent --add-port8080/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 streamcodec_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 的验证命令就固定成了三条推流、拉流、看日志。这套流程也适用于以后升级镜像版本至少能确认新镜像没有把端口或协议弄丢。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑