碰过内网服务器的人基本都体会过这种局面:装好 Docker Engine 之后,想再装 Compose,结果发现机器完全没外网,apt 拉不了包,curl 也连不上公共仓库,命令敲下去整个人卡住了。这个标题叫“Ubuntu 离线环境 安装 Docker Compose”,核心问题说白了就是:怎么在没有互联网的情况下,把一个依赖链路不短的容器编排工具搞到目标机器上正常运行。我处理过好几套这样的离线段环境,最深的感受是——离线安装不是技术瓶颈,而是准备工作做没做到位的问题。
这篇文章我会按自己实际维护服务器时的操作套路,从方案选型、联网机器上下载校验、文件传输入再到目标机器上的落地安装和验证,完整走一遍流程。适合刚接手离线段环境的新手,也适合想给自己团队整理一份内部操作文档的老手参考。
1. 离线安装的整体思路:为什么“二进制包”是首选
很多人一听到离线安装,脑子里第一反应是“那我先把 deb 包下载下来,然后 dpkg 装”。这个思路没错,但对于 Docker Compose 来说,真不一定是效率最高的路。你得先搞清楚 Docker Compose 到底是以什么形态存在的。
现在主流的 Docker Compose 有两个载体:一个是老的docker-compose独立二进制,另一个是新的docker compose子命令插件,形式不同,安装逻辑也不同。独立二进制是一个单文件,下载下来赋个执行权限就能跑;插件则通常通过docker-compose-plugin这个 deb 包安装,装好后它会作为 Docker CLI 的一个子命令出现。两种形态在离线环境下的安装难度差异很大,所以选型非常关键。
我推荐的方案很简单:优先选独立二进制。原因有两个。第一,v2 版本的独立二进制是自包含的,编译好的可执行文件会把大部分运行依赖打包进去,对操作系统的依赖极低,基本满足 glibc 版本就能运行。第二,离线环境下最怕的就是“依赖链断裂”,用单文件安装可以把不确定因素压缩到最少,你在联网机器上校验过这一个文件,到了目标机器上大概率就不会出岔子。
1.1 两条主流路线对比
我整理了一下离线安装 Docker Compose 可能走的几条路线,方便你对照自己公司的网络条件做选择。
| 安装方式 | 安装包形态 | 依赖复杂度 | 适合场景 | 维护成本 |
|---|---|---|---|---|
| 独立二进制分发 | 单个可执行文件 | 极低,几乎无额外依赖 | 离线单机、批量分发 | 低,换版本就是替换文件 |
| docker-compose-plugin 的 deb 包 | deb 包及若干依赖 | 中等,需要一并准备依赖 | 内网 apt 源完善的环境 | 中等,依赖管理交给 dpkg |
| 旧版 pip 安装 | wheel 包及 Python 依赖 | 高,容易遇到 Python 版本兼容问题 | 不推荐,v1 已进入维护模式 | 高,问题多 |
实际操作中,我还见过一种思路:在联网机器上用 pip 把 docker-compose 装好后,把 site-packages 整个目录打包拷过去。这种做法理论上可行,但坑非常多。老版 Compose 依赖了一堆 Python 库,比如 docker SDK、yaml、httplib2,这些库彼此还对 Python 小版本敏感,拷过去经常出现 import 报错或版本冲突。排查起来特别绕,性价比很低。所以除非目标环境是 Python 生态已经非常完善、且你确定只会用旧版功能,否则我不建议碰这条路。
1.2 我的选型结论:单文件分发
我在自己的维护流程里,最终定型的是“单文件分发 + 固定版本号管理”。也就是在联网机器上把对应 CPU 架构的docker-compose-linux-xxx二进制下载好,同时下载官方 sha256 校验文件,然后通过内部文件服务器或者移动介质传到目标机器。
这个方案最大的好处是确定性。你在准备阶段拿到的二进制是什么版本,生产环境跑的就是什么版本,不会有 apt 源版本漂移的问题。而且 v2 独立二进制对系统服务不产生额外侵入,卸载的时候删掉文件和软链就干净了,不会像 deb 安装那样系统里留存一堆配置痕迹。
如果你所在团队内部已经有一台完善的内网 apt 源,那么用docker-compose-plugin这个 deb 包也是可以接受的。但 deb 包的准备过程更繁琐,你要把docker-compose-plugin以及它依赖的所有包全部下载下来,逐层检查依赖关系,还要确保源里的版本和 Docker Engine 兼容。对一个只需要几台机器跑服务的环境来说,这种成本明显不划算。
2. 前期准备:在联网机器上把东西备齐
离线安装这件事,真正的操作重心其实不在目标机器上,而是在你手里的联网机器上。很多人失败,就是因为到了离线机器上才想起来“哎呀我没有这个包”“这个版本不对”,然后整个人卡死在现场。正确顺序是在出发之前,把所有文件、校验信息、版本信息全部核对完毕。
2.1 确认目标机器的架构与 Docker 版本
下载二进制之前,先确认目标机器两个关键信息:CPU 架构和 Docker Engine 版本。
架构判断用一条命令:
uname -m输出结果是x86_64的话,要选x86_64对应的二进制;输出结果是aarch64的话,要选arm64版本。这个绝对不能搞错,我在实际工作中见过有人把 x86 的包传到 ARM 机器上,一执行直接exec format error,早发现早省事。
Docker Engine 版本确认用:
docker --versionDocker Compose v2 对 Docker Engine 的版本有一定要求,老版本 Engine 配合新版本 Compose 时,有些配置项和 API 字段可能不兼容。我个人处理的标准是:目标机器的 Docker Engine 建议不低于 20.10。如果版本太老,Compose 用的部分能力可能不被支持,后面跑up的时候容易遇到云里雾里的报错。
还要顺带记录一个信息:目标机器用的 Ubuntu 是哪个版本。虽然独立二进制大多是静态编译的,对系统版本要求不高,但记录发行版信息对后续写内部维护文档会更严谨。
2.2 下载 Docker Compose 二进制与校验文件
在联网机器上,去 Docker Compose 的官方发布页面,找到你想锁定的版本。我不建议下载latest,因为离线环境一旦部署下去,未来维护时你得清楚知道每台机器上是什么版本。固定到具体版本号,方便审计也好排查。
下载时需要按架构选择资产名。比如 x86_64 架构对应docker-compose-linux-x86_64,ARM64 对应docker-compose-linux-aarch64。
除了二进制本体,一定要把官方的docker-compose-linux-x86_64.sha256这个校验文件也下载下来。校验文件里记录的是二进制对应的 SHA256 哈希值,这是防止下载过程出错、文件被改动的关键一步。很多做离线运维的兄弟嫌麻烦懒得校验,结果文件传过去才发现根本跑不了,这时候再排查网络、排查拷贝方式,浪费的都是时间。
校验做法是:
sha256sum -c docker-compose-linux-x86_64.sha256如果输出OK,说明文件完整,可以进入下一步分发;如果输出报错,别犹豫,重新下载一次。这个动作我会建议写进团队离线操作手册,作为强制性步骤。
补全脚本也可以顺手准备上。Compose 官方提供了 Bash 补全脚本,离线环境里没有网络,如果后续你天天手敲docker-compose up -d,补全能明显减少低级拼写错误。这个脚本同样放在准备好的目录里,一起带到目标机器。
2.3 准备测试用的 Compose 项目文件
在联网机器上,我还建议顺手准备一个最小的 Compose 测试文件。不一定多复杂,只要能验证 Compose 工作正常就行。我习惯用这种:
services: hello: image: busybox:latest command: "echo offline compose ok"这个 Compose 文件在离线机器上如果本地已有busybox镜像,就能直接跑起来验证整套链路;如果没有镜像,也可以用docker-compose config做纯语法校验。我后面详细说验证环节时还要用到这个文件。
把所有准备文件收进一个目录,比如~/offline-docker/,目录结构类似这样:
offline-docker/ ├── docker-compose-linux-x86_64 ├── docker-compose-linux-x86_64.sha256 ├── compose.bash └── test-compose.yaml目录结构清晰,会给后面分发过程减少很多沟通成本。
3. 离线安装的完整实操流程
准备阶段结束后,你手里已经有了干净、有校验依据的文件包。接下来就是在目标机器上真正落地的过程。我把实际操作分成传输、安装、验证、冒烟测试四步来说。
3.1 把文件传到目标机器
传输方式取决于你所在环境的物理条件。最常见的是两类:
一类是通过内部文件服务器分发。比如把文件放到公司内部的 HTTP 下载服务或者共享存储上,目标机器上直接用wget或scp拉取。这里的内部下载地址是内网资源,不涉及外网连接,安全合规。注意拉取完同样要做一次校验,防止局域网传输过程出错。
另一类是用移动介质或者本机手工拷贝。把离线包放到 U 盘或者移动硬盘,接到目标机器上手动复制。这种方式适合一次只维护少量机器。我用移动介质时习惯把文件先复制到/root/install/目录,而不是直接就在 U 盘挂载点执行安装,因为某些挂载点选项可能带了noexec,不允许执行二进制,会让你误以为文件坏了。
3.2 安装二进制并加入 PATH
文件落到目标机器后,我习惯按版本号归档,不直接把文件扔到/usr/local/bin/就完事。离线维护最怕的就是版本混乱,先建一个版本目录:
mkdir -p /opt/docker-compose/2.24.5 cp docker-compose-linux-x86_64 /opt/docker-compose/2.24.5/docker-compose chmod +x /opt/docker-compose/2.24.5/docker-compose这里有一个容易忽略的点:二进制原始文件名是docker-compose-linux-x86_64,但你真正希望执行的名字是docker-compose,所以拷贝时要改名。
接下来在PATH的目录里建立软链接。我通常推荐放到/usr/local/bin/:
ln -s /opt/docker-compose/2.24.5/docker-compose /usr/local/bin/docker-compose用软链接而不是直接复制到/usr/local/bin,好处是将来升级版本时,只需要替换/opt/docker-compose/下对应目录的二进制,软链不用变,维护起来非常干净。
执行完这两个命令后,先自检一下:
docker-compose --version正常会输出类似:
Docker Compose version v2.24.5到这里,独立二进制已经安装成功。
3.3 验证安装结果
版本号输出正常后,再验证两件事:第一,确认它确实走的是/opt里的版本;第二,确认它和 Docker Engine 能正常通信。
检查路径用:
which docker-compose如果输出/usr/local/bin/docker-compose,说明软链生效。再用一条命令看 Compose 能否读到本地 Docker 服务:
docker-compose version --short docker infodocker-compose version展示的是 Compose 自身的信息,docker info展示的是 Docker Engine 侧的信息。如果docker info正常返回,说明 Compose 后面up的时候能顺利把请求发给 Docker Engine。
这里顺便解释一个容易混淆的点:Docker Compose v2 有独立二进制形态,也有插件形态。独立二进制对应的是docker-compose命令,插件形态对应的是docker compose命令(中间没有连字符)。如果你装的是官方独立二进制,那么只有docker-compose命令可用,docker compose子命令是不存在的,除非你额外做好了插件软链配置。很多教程把两条命令混在一起讲,离线环境里要认清自己装的到底是哪一种。
3.4 用一个最小 Compose 项目做冒烟测试
版本验证没问题,不代表实际业务场景一定没问题。我会建议顺手做一次冒烟测试,用最小的开销确认 Compose 真的能把服务拉起来。
在目标机器上建一个测试目录:
mkdir -p ~/compose-test && cd ~/compose-test cp test-compose.yaml .先做离线友好的语法检查:
docker-compose config这个命令会解析 Compose 文件并输出最终的配置内容,如果 YAML 格式有问题、服务定义不合法、引用了无效配置项,都会在这里暴露。而且它不会真正启动容器,完全不需要访问镜像仓库,离线环境里特别实用。
然后尝试后台启动:
docker-compose up -d如果目标机器上本地已有busybox镜像,这条命令会直接创建一个容器并隐藏地输出启动结果。确认一切正常后,收尾清理:
docker-compose down这就完成了从安装到最小业务可用的闭环。冒烟测试也建议大家保留在离线操作文档里,以后每次给新机器装完 Compose 都跑一遍,可以尽早发现环境问题。
4. 常见问题与排查技巧实录
离线安装踩的坑,和我见到的在线环境完全不是一个套路。很多问题单看报错根本摸不着头脑,我把几个高频问题按“现象-原因-解决”的方式列出来,方便你现场对照。
| 现象 | 可能原因 | 解决办法 |
|---|---|---|
bash: docker-compose: command not found | 软链没建到 PATH 目录,或者用的用户不对 | 检查echo $PATH,确认/usr/local/bin在列;检查软链是否创建 |
Permission denied | 二进制没有执行权限,或所在挂载点是 noexec | 执行chmod +x;若在 U 盘,复制到/root/install下再尝试 |
exec format error | 二进制架构与机器 CPU 架构不匹配 | uname -m确认架构,换对应版本文件 |
docker-compose: error: ...运行到一半崩溃 | 文件下载不完整或校验值不符 | 用.sha256校验,重新下载 |
unsupported config version | Compose 版本偏老,不认识 YAML 里的配置字段 | 升级 Compose 独立二进制,或移除新版字段 |
Cannot connect to the Docker daemon | Docker Engine 没启动或DOCKER_HOST配置指向错误 | 执行systemctl status docker、docker info排查 |
第一类command not found是最常见的,我工作中见过好几次,原因看着简单,但实际上很多新手会忽略一个细节:如果你是用su切换到普通用户,而软链建在 root 的 PATH 目录,普通用户可能看不到。这时候要么让普通用户用绝对路径,要么建一个用户级软链。
第二类Permission denied值得专门强调一下,因为移动介质上的权限很容易误导人。你从 U 盘直接执行二进制,即使chmod +x设置好了,如果挂载参数带了noexec,内核会拒绝执行这个文件。报错同样是 Permission denied,但解法不是改权限,而是把文件复制到/root/install或/usr/local/bin这种正常文件系统目录下执行。这个坑特别隐蔽,一旦遇到,先排查挂载参数。
第三类exec format error我在前文也提过,主要发生在批量分发中。要是你负责维护的机器既有 x86_64 又有 ARM64,分发命令需要针对每台机器做差异化处理,不要图省事用同一个包传到底。
另一个很容易被忽略的问题是:Docker Compose 安装好了,但目标机器上 Docker Engine 本身根本没有启动。很多人会跳过docker info直接跑up -d,然后看到一个很长的连接报错,第一反应是怀疑 Compose 装坏了。所以我建议安装验证流程里把docker info作为必查项。
在排查过程中,docker-compose config是你最好的工具。离线环境没有网络,很多在线查询手段都用不上,而这个命令完全本地运行,能把配置语法问题在启动之前就暴露出来。遇到任何奇怪的报错,我建议先跑一次docker-compose config -q,把配置层面的问题排除掉,再继续往下查。
5. 离线环境后续要踩的坑:不止 Compose 本身
Compose 装好只意味着编排工具就位了,但真正跑业务时,离线环境里更大的麻烦往往是镜像。Compose 的一大核心能力是“拉取并编排镜像”,而在离线机器上,拉取动作大概率是失败的。所以安装完 Compose,建议把镜像的离线分发方案一起做了。
最朴素的做法是在联网机器上用 Docker 把镜像导出成 tar 包:
docker save -o busybox.tar busybox:latest把.tar文件传到目标机器后,用docker load导入:
docker load -i busybox.tar这样就可以让 Compose 项目在本地镜像库中找到对应镜像,正常执行up -d。
如果你的环境有内部镜像仓库,更推荐的做法是把所有需要的镜像推到内部仓库,然后在目标机器的 Docker daemon 配置里加上insecure-registries指向这个内网地址。这样 Compose 项目中的 image 字段可以直接写内网仓库路径,不用每一台机器都手动load。相比到处拷 tar 包,这个方案在后期扩容时优势很大。
批量维护多台离线机器时,还建议把你的离线安装过程固化成脚本。不要只靠“人肉执行命令”,因为每一台机器的手工操作都可能产生偏差。我自己会写一个简单的部署脚本,把版本目录创建、二进制拷贝、软链建立、版本验证全串起来,脚本里带上架构判断,进一步减少人为错误。
再补一个运维经验:离线环境的机器,操作系统补丁难以像在线环境那样及时更新,这更要求你在准备阶段把校验和信息记录做到位。我习惯在离线包目录里放一个README文件,记下 Compose 版本、架构、Docker Engine 版本要求、校验值、安装命令和测试记录。以后不管谁来维护这批机器,只需要看这个文件,就能快速了解环境状况,不用翻聊天记录重新考古。
我个人在实际操作中的体会是:离线安装 Docker Compose 这件事,技术含量其实不算高,真正考验人的是流程的严密性。准备文件、校验哈希、确认架构、固定版本、验证结果,每一步都做到位,目标机器上基本不会卡壳。反而是图方便跳过某个细节,后面的排查成本会被无限放大。如果你现在正在为内网机器准备 Docker Compose,建议按这个流程先完整走一遍,把版本和校验工作做扎实,后续再部署业务栈会顺手很多。