内网离线安装Docker与Docker-Compose:依赖备料、版本锁定与避坑指南
简介这份资源面向需要在无外网环境下部署容器运行时的运维与开发人员提供内网离线安装 Docker 及 docker-compose 的完整方案解决生产服务器、隔离机房无法联网拉取依赖的痛点。压缩包共 22 个文件约 120.91MB以 20 个 rpm 依赖包为主涵盖 docker-ce、docker-ce-cli、containerd.io、container-selinux、fuse-overlayfs、slirp4netns 等核心组件及 python、policycoreutils 等系统依赖另含 1 个 docker-compose-linux-x86_64 二进制文件和 1 个 install.sh 一键安装脚本覆盖从依赖补齐到服务启动的完整链路。已有 4706 人学习下载适合 CentOS 7 环境下需要批量、快速完成离线部署的读者参考可省去逐条排查依赖版本与顺序的繁琐过程直接复用脚本完成安装与验证。1. 内网离线安装 docker 与 docker-compose为什么值得每个运维人啃下来机房断网、生产环境隔离、客户现场只给一台跳板机——这种场景下让你装 docker在线yum install和apt-get全部失效docker compose的二进制还动不动报error while loading shared libraries: libz.so.1。内网离线安装 docker、docker-compose 这件事本质是把「联网环境下的依赖解析」提前搬到有网机器上做完再把成品搬进隔离网。它解决的不是「会不会敲命令」而是「没有外网时你怎么保证装出来的版本、依赖、systemd 单元和在线装的一模一样」。适合两类人一是要给隔离网批量铺 docker 的运维二是客户现场只有内网、却要跑 mysql8.0、redis 主从、nexus3 这类容器的交付工程师。下面按「先备料、再装 engine、再装 compose、最后排错」的顺序讲透。2. 离线包怎么备把联网机器的依赖一次性扒干净离线安装翻车九成翻在「备料不全」。你在有网机器上装得顺是因为 yum/apt 顺手把依赖也拉了到了内网缺一个libz.so.1或container-selinux就卡死。所以第一步不是装是在一台和离线机同发行版、同版本、同架构的机器上把完整依赖链导出来。2.1 先确认离线机的发行版和架构这一步别偷懒centos7和ubuntu22.04的包完全不通用x86_64和aarch64也不通用。在离线机上执行# 查看发行版和版本号 cat /etc/os-release # 查看 CPU 架构x86_64 还是 aarch64 uname -m # 查看内核版本docker 对内核有最低要求 uname -r逻辑说明/etc/os-release里的ID和VERSION_ID决定你用 yum 还是 apt 备料uname -m决定下载哪个架构的二进制。参数上docker engine 在 CentOS 7 上要求内核不低于 3.10Ubuntu 建议 20.04 及以上内核太老会出现 cgroup 挂载失败。把这三条结果记下来后面所有下载都按这个组合来。2.2 用 yumdownloader 或 apt 把依赖整包导出CentOS/RHEL 系用yumdownloader它能连依赖一起下# 安装下载工具 yum install -y yum-utils # 建目录存包 mkdir -p /opt/offline/docker-rpm # 下载 docker-ce 及其全部依赖--resolve 解析依赖--destdir 指定目录 yumdownloader --resolve --destdir/opt/offline/docker-rpm \ docker-ce docker-ce-cli containerd.io docker-compose-plugin逻辑说明--resolve是关键它会把container-selinux、libcgroup这些间接依赖一并拉下来少了它内网装到一半就报缺包。--destdir指定输出目录方便整体打包。参数上如果你要指定版本加docker-ce-24.0.7这种带版本号的写法避免下到最新版和离线机内核不兼容。Ubuntu/Debian 系没有 yumdownloader用apt-get download配合dpkg递归# 下载 deb 包到当前目录 apt-get download docker-ce docker-ce-cli containerd.io docker-compose-plugin # 递归下载依赖-R 表示递归-d 只下载不安装 apt-get install -y --download-only -R docker-ce # 把所有 deb 集中到一个目录 mkdir -p /opt/offline/docker-deb mv *.deb /opt/offline/docker-deb/逻辑说明--download-only只下不装-R递归解析依赖这样能把libz.so.1这类运行库也带下来。参数上apt-get download默认下当前源里的版本要锁版本就写docker-ce5:24.0.7-1~ubuntu.22.04~jammy。2.3 二进制方式备料不依赖包管理器的兜底方案有些内网机器连 yum 源都没有或者发行版太偏这时候用官方静态二进制最稳。docker 官方提供docker-version.tgz和docker-compose-linux-arch两个静态包解压即用不碰系统包管理器。# 假设已在有网机器下载好传到离线机 /opt/offline 下 cd /opt/offline # 解压 docker 静态二进制 tar -xzvf docker-24.0.7.tgz # 把可执行文件拷到系统路径 cp docker/* /usr/bin/ # 给 compose 二进制加执行权限并放到 PATH chmod x docker-compose-linux-x86_64 cp docker-compose-linux-x86_64 /usr/local/bin/docker-compose逻辑说明静态二进制方式绕开了container-selinux、libcgroup这些系统依赖代价是你要自己写 systemd 单元文件来托管 dockerd。参数上docker-24.0.7.tgz里的版本号要和离线机内核匹配太新的 docker 在 CentOS 7 老内核上可能起不来。这种方式适合「客户现场只有一台裸机、连 yum 源都配不了」的极端场景。提示备料阶段一定要在同版本同架构的机器上做跨版本导出的 rpm/deb 在内网装的时候会报依赖冲突这是最常见的翻车点。3. 离线装 docker enginerpm/deb 与二进制两条路怎么选备好料之后装 engine 本身反而简单难的是选对路径和把 systemd 配好。rpm/deb 方式适合有包管理器的机器二进制方式适合裸机。两条路的 systemd 单元写法不一样下面分开讲。3.1 rpm/deb 本地源安装的完整命令CentOS 系把备好的 rpm 目录做成一个本地 yum 源或者直接用yum localinstall# 方式一直接本地安装自动处理目录内依赖 cd /opt/offline/docker-rpm yum localinstall -y *.rpm # 方式二做成本地源适合批量机器 createrepo /opt/offline/docker-rpm cat /etc/yum.repos.d/local-docker.repo EOF [local-docker] namelocal docker repo baseurlfile:///opt/offline/docker-rpm enabled1 gpgcheck0 EOF yum install -y docker-ce docker-ce-cli containerd.io逻辑说明yum localinstall会读取当前目录所有 rpm 并自动解析依赖顺序适合单机createrepo建本地源适合几十台机器批量装gpgcheck0是因为离线包没有签名内网可接受。参数上baseurl用file://指向本地目录别写成 http内网没服务。Ubuntu 系用dpkg -i加apt-get -f补依赖cd /opt/offline/docker-deb # 先尝试安装缺依赖会报错 dpkg -i *.deb # 用本地缓存补依赖--no-download 禁止联网 apt-get -f install --no-download逻辑说明dpkg -i不解析依赖所以第一次大概率报缺依赖apt-get -f install --no-download会从本地 deb 缓存里补齐--no-download强制不联网防止它偷偷去外网拉包导致超时。3.2 二进制方式的 systemd 单元文件二进制方式装完dockerd 不会自动托管要手写 systemd 单元# /etc/systemd/system/docker.service [Unit] DescriptionDocker Application Container Engine Afternetwork-online.target firewalld.service Wantsnetwork-online.target [Service] Typenotify ExecStart/usr/bin/dockerd ExecReload/bin/kill -s HUP $MAINPID LimitNOFILEinfinity LimitNPROCinfinity TimeoutStartSec0 Delegateyes KillModeprocess Restarton-failure StartLimitBurst3 StartLimitInterval60s [Install] WantedBymulti-user.target逻辑说明Typenotify让 systemd 等 dockerd 就绪信号Delegateyes允许容器管理自己的 cgroupLimitNOFILEinfinity防止容器多时文件句柄不够。参数上ExecStart指向你cp到/usr/bin/的 dockerd 路径如果放别处要改这里。写完执行systemctl daemon-reload systemctl enable --now docker。3.3 启动 docker 并验证# 重载 systemd 并启动 systemctl daemon-reload systemctl enable --now docker # 查看状态确认 active (running) systemctl status docker # 验证版本和基本信息 docker version docker info逻辑说明systemctl status看有没有报failed to start常见的是 cgroup 驱动不匹配docker info里的Cgroup Driver要和 kubelet 等组件保持一致否则后面编排会出问题。参数上如果docker info报Cannot connect to the Docker daemon先查journalctl -u docker -n 50看启动日志。注意CentOS 7 上如果systemctl start docker报Failed to start Docker Application Container Engine八成是container-selinux没装或版本太低回备料阶段补上。4. 离线装 docker-compose二进制、插件与 libz 报错docker-compose 的离线安装比 engine 简单但坑更集中尤其是那个error while loading shared libraries: libz.so.1几乎每个离线装 compose 的人都遇到过。这一章把二进制、插件两种形态和这个报错的根因讲清楚。4.1 二进制方式装 docker-composedocker-compose v2 之后官方推荐用插件形态但独立二进制仍然可用适合老脚本# 把备好的二进制放到 PATH cp /opt/offline/docker-compose-linux-x86_64 /usr/local/bin/docker-compose chmod x /usr/local/bin/docker-compose # 验证 docker-compose version逻辑说明/usr/local/bin在默认 PATH 里放这里全局可用。chmod x别忘否则报Permission denied。参数上二进制文件名带架构后缀aarch64 机器要换成对应架构的包别拿 x86_64 的硬塞。4.2 插件方式装 docker composedocker compose v2 作为 CLI 插件调用方式是docker compose中间空格不是docker-compose# 插件目录docker 会从这里加载 mkdir -p /usr/local/lib/docker/cli-plugins # 放入插件二进制命名必须是 docker-compose cp /opt/offline/docker-compose-linux-x86_64 \ /usr/local/lib/docker/cli-plugins/docker-compose chmod x /usr/local/lib/docker/cli-plugins/docker-compose # 验证注意是 docker compose 不是 docker-compose docker compose version逻辑说明插件目录路径是 docker 约定的/usr/local/lib/docker/cli-plugins是全局插件位置也可以放~/.docker/cli-plugins只对当前用户生效。文件名必须是docker-composedocker 靠文件名识别插件。参数上如果docker compose version报docker: compose is not a docker command说明插件目录不对或文件名错了。4.3 libz.so.1 报错的根因和修法docker-compose: error while loading shared libraries: libz.so.1: failed to m这个报错根因是 compose 二进制依赖系统的 zlib 库而离线机缺zlib或zlib-devel。# 先确认系统有没有 libz ldconfig -p | grep libz # 如果没有从备料里补装 # CentOS rpm -ivh /opt/offline/deps/zlib-1.2.11-*.rpm # Ubuntu dpkg -i /opt/offline/deps/zlib1g_*.deb # 刷新动态链接库缓存 ldconfig逻辑说明ldconfig -p列出系统已注册的动态库grep libz看有没有libz.so.1。没有就补装 zlib 包装完必须ldconfig刷新缓存否则新库不会被识别。参数上zlib 版本要和系统架构匹配别下错架构。这个报错和 docker engine 无关纯粹是 compose 二进制的运行库缺失补上就好。提示如果补了 zlib 还报同样的错用ldd /usr/local/bin/docker-compose | grep not found看还缺哪些库一次性补全别一个个试。5. 避坑与排查离线装 docker 最常见的 5 个翻车现场离线环境没有外网兜底出问题只能靠日志和依赖分析。下面 5 条是我在内网交付里踩过的真实坑按「现象 → 原因 → 解决」写照着排查能省大半天。5.1 现象docker 服务启动失败日志报 cgroup 相关错误原因离线机内核的 cgroup 版本和 docker 默认驱动不匹配CentOS 7 默认 cgroup v1新 docker 可能默认走 systemd 驱动但内核没配好。解决编辑/etc/docker/daemon.json显式指定驱动{ exec-opts: [native.cgroupdriversystemd], log-driver: json-file, log-opts: {max-size: 100m} }改完systemctl daemon-reload systemctl restart docker。如果还不行把systemd换成cgroupfs再试两者选能起来的那个。5.2 现象yum localinstall 报依赖冲突装到一半退出原因备料机器和离线机的系统小版本不一致比如一个是 CentOS 7.6 一个是 7.9rpm 依赖的glibc版本对不上。解决备料机器必须和离线机cat /etc/redhat-release完全一致。已经装了一半的先yum remove清掉残留再重新导包。实在对不齐改用二进制方式绕开包管理器。5.3 现象docker-compose 报 libz.so.1 缺失补了 zlib 还报原因补装的 zlib 架构不对或者ldconfig没执行动态链接器没找到新库。解决file /opt/offline/deps/zlib*.rpm确认架构ldd $(which docker-compose)看具体缺哪个补完执行ldconfig再docker-compose version验证。5.4 现象docker 装好了但docker pull拉不到镜像原因离线机没外网默认去 Docker Hub 拉必然超时。解决在有网机器docker save导出镜像为 tar传到离线机docker load导入# 有网机器导出 docker save -o mysql8.tar mysql:8.0 # 离线机导入 docker load -i mysql8.tar参数上docker save可以一次导多个镜像docker load会保留原有 tag导入后docker images能看到。5.5 现象非 root 用户执行 docker 报权限错误原因docker 守护进程的 socket 默认只有 root 能访问。解决把用户加入 docker 组usermod -aG docker youruser # 重新登录或执行 newgrp docker参数上-aG是追加到组别用-G否则会覆盖用户原有组。改完必须重新登录才生效newgrp只对当前会话临时生效。6. 批量交付与版本锁定让离线安装可复现的两个技巧单机装完只是开始内网交付往往是几十台机器还要保证每次装出来的版本一致。这一章讲两个我常用的技巧用脚本把整个流程固化用版本清单锁死依赖。6.1 把安装流程写成一个可重复执行的脚本手工敲命令在批量场景下必然出错我一般把备料和安装写成两个脚本备料在有网机器跑安装在离线机跑。#!/bin/bash # install-docker-offline.sh在离线机执行 set -e OFFLINE_DIR/opt/offline # 1. 安装 engine cd ${OFFLINE_DIR}/docker-rpm yum localinstall -y *.rpm # 2. 配置 daemon mkdir -p /etc/docker cat /etc/docker/daemon.json EOF { exec-opts: [native.cgroupdriversystemd], log-driver: json-file, log-opts: {max-size: 100m, max-file: 3} } EOF # 3. 启动 systemctl daemon-reload systemctl enable --now docker # 4. 装 compose 插件 mkdir -p /usr/local/lib/docker/cli-plugins cp ${OFFLINE_DIR}/docker-compose-linux-x86_64 \ /usr/local/lib/docker/cli-plugins/docker-compose chmod x /usr/local/lib/docker/cli-plugins/docker-compose # 5. 验证 docker version docker compose version echo install done逻辑说明set -e让脚本遇错即停避免装一半继续跑daemon.json里max-file限制日志文件数量防止内网磁盘被日志撑爆。参数上OFFLINE_DIR按实际路径改脚本里所有路径都基于它方便整体迁移。这个脚本我在多个客户现场用过改改路径就能跑。6.2 用版本清单锁死依赖避免「这次能装下次不能」离线安装最怕的是「这次装成功下次换台机器就失败」根因是依赖版本漂移。我的做法是维护一个manifest.txt记录每个包的精确版本和校验和。组件版本架构校验方式docker-ce24.0.7x86_64sha256containerd.io1.6.25x86_64sha256docker-compose-plugin2.23.0x86_64sha256zlib1.2.11x86_64sha256逻辑说明每次备料后更新这张表安装前用sha256sum -c校验包完整性防止传输过程中损坏。参数上版本号要写全别写latest离线环境没有latest的概念。这张表跟着离线包一起交付下次换机器直接照表备料能复现出完全一样的环境。6.3 验证安装结果的三条命令装完别急着走跑这三条确认# 1. engine 和 compose 版本都能出来 docker version docker compose version # 2. 跑一个最小容器验证运行时 docker run --rm hello-world # 3. 确认 cgroup 驱动和日志配置生效 docker info | grep -E Cgroup Driver|Logging Driver逻辑说明hello-world是最小验证能跑通说明 engine、containerd、runc 三层都正常docker info确认驱动和日志配置避免后面编排时才发现驱动不匹配。参数上--rm让容器跑完自动删除不留垃圾。我自己的习惯是每次内网交付前先在测试机把这三个脚本跑一遍确认无误再进客户现场。离线安装这事后悔药就是提前把依赖备全、把版本锁死现场少一次翻车就多一分交付底气。希望帮到你。本文还有配套的精品资源点击获取