内网离线安装Docker与docker-compose实战指南
简介本资源专为内网隔离环境下的Linux系统运维人员设计解决无外网连接时无法在线安装Docker及Docker-Compose的核心痛点适用于政企、金融、科研等强安全管控场景的CentOS 7离线部署需求。压缩包共22个文件含20个RPM依赖包覆盖containerd.io、docker-ce、docker-ce-cli、fuse-overlayfs、slirp4netns等核心组件及SELinux、Python、libsemanage等必要运行时依赖、1个可执行安装脚本install.sh实现一键自动化部署和1个预编译的docker-compose-linux-x86_64二进制文件整体体积120.91MB开箱即用无需额外下载。目前已有4706人学习下载读者可直接获取完整离线安装链路从基础依赖到容器引擎再到编排工具包含全部版本对齐的rpm包与适配脚本显著规避因依赖缺失、架构不匹配或权限策略导致的安装失败问题大幅缩短内网环境容器平台搭建周期。1. 内网离线安装 Docker 与 docker-compose为什么你总在“断网那一刻”才想起它某次现场交付客户机房网络策略极严——所有出口流量被物理隔离连 ping 外网都超时。而部署脚本里那行curl -fsSL https://get.docker.com | sh直接卡死后面 17 个服务一个都起不来。这不是玄学是内网环境的日常没有包管理器源、没有 pip index、没有 GitHub clone 权限甚至连apt update都报Could not resolve archive.ubuntu.com。内网离线安装 Docker 与 docker-compose本质不是“把两个二进制丢进去”而是构建一套可验证、可复用、可审计的离线依赖闭环系统从内核模块检查、cgroup v2 兼容性、containerd 运行时绑定到 compose 的 Python 环境隔离与二进制签名校验。它适合三类人政企信创项目交付工程师、工业控制现场运维、以及所有被“最后一公里网络”反复背刺过的容器化落地者。本文不讲 Docker 是什么只讲怎么在没网的 CentOS 7.9 或 Ubuntu 22.04 上用 U 盘拷贝 3 个 tar 包15 分钟内让docker run hello-world和docker-compose up -d同时亮绿灯。2. 离线包选型与本地镜像准备别再用docker save打包整个 registry2.1 为什么必须分三层打包Docker 引擎 / containerd / CLI 工具链Docker 官方自 20.10 版本起已将dockerd、containerd、runc、docker-cli拆为独立发布周期。离线安装若只下docker-ce-cli-24.0.7-1.el7.x86_64.rpm会因缺失containerd.io-1.7.20-1.el7.x86_64.rpm而启动失败——错误日志里不会明说缺 containerd只会报failed to start daemon: failed to dial /run/containerd/containerd.sock。常见做法是去 download.docker.com 对应路径下按 OS 发行版和架构一次性下载四类包docker-ce-version核心守护进程docker-ce-cli-version客户端命令containerd.io-versionCRI 运行时docker-buildx-plugin-version可选但 CI 场景必备提示Ubuntu 用户注意.deb包名含amd64/arm64CentOS/RHEL 用户注意el7/el8/el9后缀必须与uname -r输出的内核版本严格匹配。el7包在 el8 系统上强制安装会破坏 systemd 依赖。2.2 docker-compose 离线方案二进制 vs pip wheel为什么我坚持用docker-compose-linux-x86_64docker-compose自 v2.20 起已完全脱离 Python 生态提供纯静态链接二进制 github.com/docker/compose/releases 。但很多团队仍用pip3 install docker-compose --find-links file:///path/to/wheelhouse --no-index这埋了三个雷pip本身需提前离线安装get-pip.pysetuptoolswheel三重依赖docker-composewheel 依赖docker-py而后者又依赖requests、urllib3等离线 wheel 数量常超 20 个Python 版本锁死Python 3.8 wheel 在 3.11 环境下直接ImportError。我一般会直接下载官方二进制# 在有网机器执行以 Ubuntu 22.04 x86_64 为例 wget https://github.com/docker/compose/releases/download/v2.25.0/docker-compose-linux-x86_64 chmod x docker-compose-linux-x86_64 sudo mv docker-compose-linux-x86_64 /usr/local/bin/docker-compose验证docker-compose version应输出Docker Compose version v2.25.0且ldd /usr/local/bin/docker-compose显示not a dynamic executable证明是静态链接。2.3 必备基础镜像离线缓存hello-world 不是玩具是启动探针离线环境最易被忽略的是runtime 验证镜像。docker run hello-world成功 ≠ Docker 正常因为该镜像仅 13KB不触发存储驱动overlay2、不加载 cgroups、不测试网络插件。真正能暴露问题的是alpine:3.19或nginx:alpine——它们会触发镜像解压、layer mount、seccomp profile 加载。正确做法在有网机器拉取并保存为 tar# 拉取最小验证集含基础运行时探针 docker pull hello-world:latest docker pull alpine:3.19 docker pull nginx:alpine # 导出为单 tar非分层防离线导入失败 docker save hello-world:latest alpine:3.19 nginx:alpine -o offline-images.tar该 tar 文件后续通过docker load -i offline-images.tar导入比逐个docker pull更可靠——它绕过了 DNS 解析、证书校验、registry 认证三道关卡。3. 离线安装全流程从内核检查到 daemon 启动成功的 7 个原子步骤3.1 步骤 1内核与模块预检90% 的翻车发生在这里Docker 要求内核 ≥ 3.10CentOS 7 默认 3.10.0-1160但关键不在版本号而在cgroup、namespaces、aufs/overlay2 支持。执行# 检查必需内核配置必须全为 y 或 m zcat /proc/config.gz 2/dev/null | grep -E CONFIG_(CGROUP|NAMESPACES|OVERLAY_FS)y|CONFIG_CGROUPSy || \ gunzip -c /boot/config-$(uname -r) 2/dev/null | grep -E CONFIG_(CGROUP|NAMESPACES|OVERLAY_FS)y|CONFIG_CGROUPSy # 检查 overlay2 模块是否可用CentOS 7 需手动加载 modprobe overlay echo $? # 应为 0 lsmod | grep overlay # 应有输出若modprobe overlay报错Module overlay not found说明内核未编译该模块。此时不能强行yum install kernel-modules-extra可能引发内核版本错配而应查uname -r输出如3.10.0-1160.el7.x86_64在相同版本的在线 CentOS 7 机器上执行yum install kernel-modules-extra-3.10.0-1160.el7.x86_64将生成的/lib/modules/3.10.0-1160.el7.x86_64/kernel/fs/overlayfs/overlay.ko.xz拷贝至离线机/lib/modules/$(uname -r)/kernel/fs/overlayfs/xz -d overlay.ko.xz depmod -a modprobe overlay3.2 步骤 2RPM/DEB 包批量安装与依赖解析Ubuntu 22.04 离线安装.deb 方案# 假设 deb 包已放于 /tmp/docker-offline/ cd /tmp/docker-offline/ # 按依赖顺序安装containerd 必须在 docker-ce 之前 sudo dpkg -i containerd.io_1.7.20-1_amd64.deb sudo dpkg -i docker-ce-cli_24.0.7-1_amd64.deb sudo dpkg -i docker-ce_24.0.7-1_amd64.deb # 修复可能缺失的依赖如 libseccomp2 sudo apt-get install -f -y参数说明dpkg -i是原子安装但不解决依赖apt-get install -f会扫描/var/lib/dpkg/status中标记为half-installed的包并补全依赖。这是 Ubuntu 离线安装的后悔药。CentOS 7.9 离线安装.rpm 方案# 按严格顺序安装顺序错则 dockerd 启动失败 sudo rpm -ivh containerd.io-1.7.20-1.el7.x86_64.rpm sudo rpm -ivh docker-ce-cli-24.0.7-1.el7.x86_64.rpm sudo rpm -ivh docker-ce-24.0.7-1.el7.x86_64.rpm # 若报错 Failed dependencies: systemd 219说明系统 systemd 版本过低 # 此时不能升级 systemd风险极高改用 docker-ce-20.10.x兼容 systemd 219注意rpm -ivh中的vverbose和hhash必须带上可实时看到文件解压进度避免误判为卡死。3.3 步骤 3dockerd 配置文件初始化与 cgroup 驱动对齐Docker 默认使用cgroupfs驱动但 Kubernetes 要求systemd。离线环境若未来要对接 K8s必须在首次启动前对齐# 创建 daemon.json覆盖默认配置 sudo tee /etc/docker/daemon.json -EOF { exec-opts: [native.cgroupdriversystemd], log-driver: json-file, log-opts: { max-size: 100m, max-file: 3 }, storage-driver: overlay2, insecure-registries: [192.168.100.0/24] } EOF # 重载 systemd 配置 sudo systemctl daemon-reload关键参数说明native.cgroupdriversystemd强制 dockerd 使用 systemd cgroup 管理避免与 kubelet 冲突storage-driver: overlay2显式声明存储驱动防止内核不支持时 fallback 到 aufs已废弃insecure-registries内网私有 registry 地址段跳过 TLS 校验生产环境应配内网 CA。3.4 步骤 4启动服务并验证 socket 权限# 启动服务不加 --now 则不自动启用开机自启 sudo systemctl start docker # 检查状态重点看 Active: active (running) 和 cgroup driver sudo systemctl status docker | grep -E (Active:|cgroup) # 验证 socket 文件权限非 root 用户需加入 docker 组 ls -l /var/run/docker.sock # 应输出srw-rw---- 1 root docker 0 ... /var/run/docker.sock若systemctl status docker显示failed to start daemon立即执行sudo journalctl -u docker -n 50 --no-pager | grep -E (levelerror|failed|cannot)90% 的错误集中于failed to start containerdcontainerd 包未装、cgroup controller memory not enabled内核未开启 CONFIG_MEMCG、overlay2: cannot mount/var/lib/docker 权限错误。3.5 步骤 5用户组与权限固化让普通用户也能跑容器# 创建 docker 组若不存在 sudo groupadd docker 2/dev/null || true # 将当前用户加入 docker 组 sudo usermod -aG docker $USER # 重新加载组信息无需登出但新 shell 才生效 newgrp docker # 验证非 root 用户执行 docker run --rm hello-world注意newgrp docker会启动新 shell原 shell 仍无权限。若需在当前 shell 生效改用exec su -l $USER但会丢失当前环境变量。3.6 步骤 6docker-compose 权限与符号链接标准化# 下载的二进制已放 /usr/local/bin/docker-compose但需确保可执行 sudo chmod x /usr/local/bin/docker-compose # 创建标准符号链接适配旧脚本中写的 docker-compose sudo ln -sf /usr/local/bin/docker-compose /usr/local/bin/docker-compose-v2 # 验证版本与动态库静态二进制应无依赖 docker-compose version ldd $(which docker-compose) 21 | head -5若ldd输出含libpthread.so.0 /lib64/libpthread.so.0等则非静态二进制需重新下载docker-compose-linux-x86_64。3.7 步骤 7离线镜像加载与首个 compose 服务验证# 加载离线镜像包 sudo docker load -i /tmp/offline-images.tar # 编写最小 docker-compose.yml验证网络与卷 cat /tmp/test-compose.yml -EOF version: 3.8 services: nginx-test: image: nginx:alpine ports: - 8080:80 volumes: - /tmp/nginx-html:/usr/share/nginx/html volumes: nginx-html: EOF # 创建测试页面 echo h1Offline Docker OK/h1 | sudo tee /tmp/nginx-html/index.html # 启动并验证 sudo docker-compose -f /tmp/test-compose.yml up -d curl -s http://localhost:8080 | grep Offline Docker OK echo ✅ compose 启动成功此步骤同时验证了镜像加载、volume 挂载、端口映射、compose 解析能力——四者任一失败都会导致curl返回空或 connection refused。4. 避坑内网离线安装 Docker 的 5 个血泪经验4.1 现象systemctl start docker后立即退出journalctl 显示failed to start containerd原因containerd.ioRPM/DEB 包未安装或安装顺序错误docker-ce 在 containerd 之前安装。解决执行rpm -qa | grep containerdCentOS或dpkg -l | grep containerdUbuntu确认containerd.io已存在若存在检查/usr/bin/containerd是否可执行containerd --version是否输出版本号。4.2 现象docker info报错Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?原因/var/run/docker.sock文件存在但权限为srw-rw---- 1 root rootroot 组而非 docker 组。解决执行sudo chown root:docker /var/run/docker.sock然后sudo systemctl restart docker。4.3 现象docker run alpine:3.19 ls卡住无输出docker ps显示容器状态为Created原因内核未启用CONFIG_NET_NSynetwork namespace导致容器无法初始化网络栈。解决检查zcat /proc/config.gz | grep CONFIG_NET_NS若为m则需modprobe netns若为n则需更换内核或使用--network none启动。4.4 现象docker-compose up报错ERROR: for nginx-test Cannot create container for service nginx-test: invalid mount config for type bind原因compose 文件中volumes路径为相对路径如./html而离线机当前工作目录与编写环境不同。解决所有volumes必须用绝对路径如/tmp/nginx-html或在docker-compose.yml顶部添加volumes:块声明命名卷如示例中的nginx-html:。4.5 现象docker load -i offline-images.tar后docker images为空原因tar 包由docker save生成时未指定-o输出到文件而是重定向导致 tar 头部损坏。解决重新生成 tardocker save hello-world:latest -o fixed.tar用-o参数不用或用file fixed.tar检查是否为POSIX tar archive若显示data则已损坏。5. 进阶技巧构建可复用的离线安装包生成器5.1 用 Bash 脚本自动化离线包采集适配多 OS手动下载 10 个 RPM/DEB 包极易遗漏版本。我写了一个gen-offline-bundle.sh输入 OS 类型和 Docker 版本自动下载全部依赖#!/bin/bash # gen-offline-bundle.sh OS$1 # ubuntu22 or centos7 VERSION$2 # 24.0.7 if [[ $OS ubuntu22 ]]; then BASE_URLhttps://download.docker.com/linux/ubuntu/dists/jammy/pool/stable/amd64 PKGS(containerd.io_${VERSION}-1_amd64.deb docker-ce-cli_${VERSION}-1_amd64.deb docker-ce_${VERSION}-1_amd64.deb) elif [[ $OS centos7 ]]; then BASE_URLhttps://download.docker.com/linux/centos/7/x86_64/stable/Packages PKGS(containerd.io-${VERSION}-1.el7.x86_64.rpm docker-ce-cli-${VERSION}-1.el7.x86_64.rpm docker-ce-${VERSION}-1.el7.x86_64.rpm) fi mkdir -p offline-bundle/$OS for pkg in ${PKGS[]}; do wget $BASE_URL/$pkg -O offline-bundle/$OS/$pkg done # 下载 docker-compose 二进制 COMPOSE_URLhttps://github.com/docker/compose/releases/download/v2.25.0/docker-compose-linux-x86_64 wget $COMPOSE_URL -O offline-bundle/$OS/docker-compose chmod x offline-bundle/$OS/docker-compose执行./gen-offline-bundle.sh centos7 24.0.710 秒生成完整离线包目录。该脚本已用于某高校实验室 12 台离线服务器批量部署。5.2 离线环境下的镜像仓库轻量化方案registry nginx 反向代理内网不可能每次部署都docker load需私有 registry。但docker distribution官方 registry 镜像需联网拉取。解决方案在有网机器docker pull registry:2→docker save registry:2 -o registry.tar离线机docker load -i registry.tar启动 registry禁用 TLS用 nginx 做反向代理加 HTTPSdocker run -d \ --restartalways \ --name registry \ -v /opt/registry/data:/var/lib/registry \ -e REGISTRY_HTTP_ADDR0.0.0.0:5000 \ -p 5000:5000 \ registry:2配置 nginx 将https://reg.internal反向代理到http://localhost:5000并注入自签名证书。这样离线机docker login reg.internal后即可docker push reg.internal/app:v1彻底摆脱镜像搬运。5.3 验证清单离线安装成功后的 5 项必检指标检查项命令期望输出失败含义1. dockerd 进程存活ps aux | grep dockerd含/usr/bin/dockerd --hostfd://...daemon 未启动或崩溃2. containerd 进程存活ps aux | grep containerd含/usr/bin/containerd运行时未就绪Docker 无法调度容器3. overlay2 存储驱动就绪docker info | grep Storage DriverStorage Driver: overlay2镜像层无法解压docker pull失败4. 非 root 用户可执行id | grep docker输出含docker组权限未同步交付脚本需 sudo5. compose 解析 YAMLdocker-compose -f (echo version: \3.8\) config输出services: {}compose 二进制损坏或版本不兼容我的习惯是把这 5 条命令写成verify-offline.sh每次交付前在目标机运行输出✅ All checks passed才签字。这比口头承诺可靠得多。希望帮到你。本文还有配套的精品资源点击获取