☰
离线环境Docker与Docker-Compose安装包部署实战指南
2026/9/29 15:15:46 网站建设 项目流程

简介:本资源面向需要在 Linux 环境下快速搭建容器运行环境的开发与运维人员,提供 Docker 及 Docker Compose 的离线安装包,解决内网或受限网络下无法直接拉取安装文件的问题。压缩包共 4 个文件,约 84.53MB,包含 tgz 二进制安装包、docker-compose 编排文件、service 系统服务配置以及 sh 安装脚本,覆盖从解压、注册服务到启动编排的完整链路,适合具备基础 Linux 操作能力、希望省去逐条命令配置的读者。目前已有 265 人学习下载,可作为搭建测试环境或部署多容器应用的参考。通过其中的安装脚本与服务配置,读者能快速完成 Docker 环境初始化,并借助 Compose 文件一键管理多容器应用,减少手动配置带来的排错成本。

1. docker和docker-compose安装包:离线环境里那套能救命的二进制组合

机房断外网、内网机器只开 22 端口、甲方要求所有软件必须走安全审计——这种场景下,apt install docker-ce和yum install docker-compose基本等于废命令。你真正需要的是两个能塞进 U 盘、拷到目标机器上直接跑的静态二进制包:docker和docker-compose。这套组合不依赖包管理器、不挑发行版、不需要联网拉依赖,解压、赋权、扔进 PATH 就能用。它解决的核心问题只有一个:在完全离线的 Linux 环境里,把容器运行时和编排工具一次性部署到位。适合谁?做私有化交付的运维、驻场实施、内网开发环境搭建的人,以及被docker-compose 2.32.1下载这类搜索词反复折磨过的同行。下面按我实际交付过十几套内网环境的路径,把选包、装包、验证、排错讲透。

2. 先搞清楚你要的是哪个包:docker、docker-compose 和 docker desktop 的边界

2.1 三个名字对应三种完全不同的东西

很多人搜「docker和docker-compose安装包」时,脑子里其实混着三个概念。第一个是docker engine,也就是dockerd守护进程加docker客户端,这是真正跑容器的核心。第二个是docker-compose,一个独立的 Go 二进制,用来解析docker-compose.yml并调用 docker API 批量管理容器。第三个是docker desktop,那是 Windows 和 macOS 上的桌面套件,带图形界面、带虚拟机、带 Kubernetes,和 Linux 服务器上的离线安装完全是两条路。

如果你在 Windows 上看到virtualization support not detected docker desktop failed to start这类报错,那是 Docker Desktop 的 WSL2 或 Hyper-V 虚拟化没开,和本文讲的 Linux 二进制包不是一回事。反过来,如果你在 CentOS 7 上执行docker-compose up提示command not found,那才是本文要解决的问题。

注意:Docker Desktop 的汉化包、离线安装包属于桌面端范畴,服务器交付场景直接跳过,不要混用。

2.2 为什么离线环境优先选静态二进制而不是 rpm/deb

包管理器安装 docker 的典型流程是yum install -y yum-utils→yum-config-manager --add-repo→yum install docker-ce。这条链路里每一步都要联网,而且不同发行版、不同版本之间的依赖关系能把人逼疯。我遇到过最离谱的一次:内网 CentOS 7.9 缺container-selinux的某个小版本,rpm 包死活装不上,最后从另一台机器上rpm -e --nodeps强拆才绕过。

静态二进制包的好处是:官方已经把dockerd、docker、containerd、runc、docker-proxy这些组件编译好并打包在一起,解压即用。它不碰系统包数据库,不依赖 glibc 之外的动态库,升级和回滚就是替换目录。对于「装完就跑、跑完就走」的交付场景,这是最省心的路径。

2.3 版本怎么选:别追最新,追稳定和匹配

docker engine 的版本号格式是YY.MM.PATCH,比如24.0.7、26.1.4。docker-compose 从 v2 开始改成了v2.x.y的格式,并且官方推荐用docker compose(作为 docker CLI 插件)而不是独立的docker-compose命令。但在离线环境里,独立二进制docker-compose反而更灵活,因为它不依赖 docker CLI 的插件目录结构。

我的选版原则是:docker engine 选比当前最新稳定版落后一个小版本的,比如最新是 27.x,我就选 26.1.x。docker-compose 选 v2.20 以上的版本,因为从 v2.20 开始对compose.yaml新规范的支持才完整。热搜里出现的docker-compose 2.32.1下载说明这个版本有人在用,但我不建议盲目追这个号,先确认你的docker-compose.yml里有没有用到profiles、depends_on的条件语法,有的话至少 v2.20+。

组件推荐版本区间选版理由
docker engine24.0.x ~ 26.1.x稳定、社区资料多、兼容性好
docker-composev2.20 ~ v2.32支持 compose 规范新特性
containerd随 engine 包附带不要单独升级,容易版本错配
runc随 engine 包附带同上

2.4 下载渠道:从哪拿包才不翻车

官方下载地址是download.docker.com/linux/static/stable/x86_64/,目录下按版本号排列着docker-26.1.4.tgz这样的文件。docker-compose 的独立二进制在 GitHub releases 页面,文件名类似docker-compose-linux-x86_64。如果你在内网,提前在外网机器上下好,校验 SHA256,再拷进去。

提示:下载完先sha256sum对一下官方公布的校验值,我吃过一次包被中间设备篡改的亏,解压后dockerd启动直接段错误。

3. 离线安装 docker engine:从解压到 systemd 托管的完整命令链

3.1 解压与目录规划

假设你已经把docker-26.1.4.tgz拷到了/tmp。这个压缩包里是一个docker/目录,里面躺着所有二进制文件。不要直接解压到/usr/bin,先解到临时目录看清楚内容。

# 进入存放安装包的目录 cd /tmp # 查看压缩包内容,确认包含哪些二进制 tar -tzf docker-26.1.4.tgz # 解压到当前目录,会生成 docker/ 文件夹 tar -xzf docker-26.1.4.tgz # 查看解压出来的文件列表 ls -lh docker/

执行完ls你应该看到containerd、containerd-shim-runc-v2、ctr、docker、dockerd、docker-init、docker-proxy、runc这些文件。其中dockerd是守护进程,docker是客户端,containerd和runc是底层运行时。

参数说明:-t是列出内容,-x是解压,-z是 gzip 解压,-f指定文件名。这四个参数组合-tzf和-xzf是 tar 操作 tgz 包的标准写法,顺序不能乱。

3.2 拷贝二进制并设置权限

确认文件无误后,把它们拷到/usr/bin/。注意containerd-shim-runc-v2这个文件必须和containerd在同一目录,否则 containerd 启动时会找不到 shim。

# 将 docker 目录下所有二进制拷贝到 /usr/bin sudo cp docker/* /usr/bin/ # 给所有二进制加上可执行权限 sudo chmod +x /usr/bin/docker* sudo chmod +x /usr/bin/containerd* sudo chmod +x /usr/bin/ctr sudo chmod +x /usr/bin/runc # 验证 docker 客户端能否正常输出版本 docker --version

如果docker --version输出了Docker version 26.1.4, build 5650f9b,说明客户端二进制没问题。但此时dockerd还没跑起来,docker info会报Cannot connect to the Docker daemon,这是正常的。

3.3 配置 systemd 单元文件

静态二进制包不带 systemd 配置,需要手写。创建/etc/systemd/system/docker.service,内容如下:

[Unit] Description=Docker Application Container Engine Documentation=https://docs.docker.com After=network-online.target firewalld.service Wants=network-online.target [Service] Type=notify ExecStart=/usr/bin/dockerd ExecReload=/bin/kill -s HUP $MAINPID LimitNOFILE=infinity LimitNPROC=infinity LimitCORE=infinity TimeoutStartSec=0 Delegate=yes KillMode=process Restart=on-failure StartLimitBurst=3 StartLimitInterval=60s [Install] WantedBy=multi-user.target

同时创建/etc/systemd/system/containerd.service:

[Unit] Description=containerd container runtime Documentation=https://containerd.io After=network.target [Service] ExecStartPre=/sbin/modprobe overlay ExecStart=/usr/bin/containerd Delegate=yes KillMode=process Restart=always RestartSec=5 LimitNPROC=infinity LimitCORE=infinity LimitNOFILE=infinity TasksMax=infinity OOMScoreAdjust=-999 [Install] WantedBy=multi-user.target

ExecStartPre=/sbin/modprobe overlay这行很关键,它确保 overlay2 存储驱动需要的内核模块在 containerd 启动前加载。如果你的内核已经内置了 overlay 模块,这行也不会报错。

3.4 启动与开机自启

# 重新加载 systemd 配置 sudo systemctl daemon-reload # 先启动 containerd sudo systemctl start containerd sudo systemctl enable containerd # 再启动 docker sudo systemctl start docker sudo systemctl enable docker # 检查两个服务的状态 sudo systemctl status containerd --no-pager sudo systemctl status docker --no-pager

systemctl status输出里看到Active: active (running)就对了。如果 docker 启动失败,先看journalctl -u docker -n 50 --no-pager,九成问题出在存储驱动或 iptables 上。

3.5 验证安装:跑一个最小容器

# 用 hello-world 镜像验证 docker 能否正常拉取和运行容器 docker run --rm hello-world

离线环境下这条命令会失败,因为拉不到镜像。正确的验证方式是提前docker save一个镜像成 tar 包,拷到目标机器后docker load进去,再跑。或者直接docker info看输出里Server Version和Storage Driver是否正常。

# 查看 docker 服务端信息,确认存储驱动和 cgroup 驱动 docker info | grep -E "Server Version|Storage Driver|Cgroup Driver|Kernel Version"

输出里Storage Driver: overlay2和Cgroup Driver: systemd是我最希望看到的组合。如果是cgroupfs,在 Kubernetes 场景下会有隐患,需要额外配置。

4. 离线安装 docker-compose:一个二进制文件的事,但坑不少

4.1 下载与放置

docker-compose v2 的独立二进制就是一个文件,从 GitHub releases 下载docker-compose-linux-x86_64,拷到目标机器。

# 将下载的二进制放到 /usr/local/bin 并重命名 sudo cp docker-compose-linux-x86_64 /usr/local/bin/docker-compose # 赋予可执行权限 sudo chmod +x /usr/local/bin/docker-compose # 验证版本 docker-compose --version

如果输出Docker Compose version v2.24.5,说明安装成功。/usr/local/bin通常在 PATH 里,如果不在,用echo $PATH确认,或者直接放到/usr/bin。

4.2 为什么不用 docker compose 插件方式

docker-compose v2 也支持作为 docker CLI 插件安装,路径是~/.docker/cli-plugins/docker-compose或/usr/local/lib/docker/cli-plugins/docker-compose。这种方式的好处是可以用docker compose(中间是空格)调用,和 docker 命令集成更紧密。

但在离线交付场景里,我倾向于独立二进制方式,原因有三:第一,插件目录在不同 docker 版本里路径可能变;第二,独立二进制不依赖 docker CLI 的插件发现机制;第三,出问题时排查路径更短,直接which docker-compose就能定位。

注意:如果你同时装了独立二进制和插件,docker compose和docker-compose可能指向不同版本,用docker-compose version和docker compose version分别确认。

4.3 用 docker-compose 跑一个离线 Redis 主从

热搜里有人搜docker安装redis主从,这里给一个离线可用的 compose 文件示例。前提是你已经docker load了 redis 镜像。

# docker-compose-redis.yml version: "3.8" services: redis-master: image: redis:7.2 container_name: redis-master command: redis-server --appendonly yes ports: - "6379:6379" volumes: - ./data/master:/data networks: - redis-net redis-slave: image: redis:7.2 container_name: redis-slave command: redis-server --appendonly yes --replicaof redis-master 6379 ports: - "6380:6379" volumes: - ./data/slave:/data depends_on: - redis-master networks: - redis-net networks: redis-net: driver: bridge

启动命令:

# 后台启动 Redis 主从 docker-compose -f docker-compose-redis.yml up -d # 查看容器状态 docker-compose -f docker-compose-redis.yml ps # 验证主从复制是否生效 docker exec redis-master redis-cli info replication | grep connected_slaves

connected_slaves:1说明从节点已连上。如果为 0,检查redis-slave的日志docker logs redis-slave,常见原因是replicaof后面的主机名解析不到,确认两个容器在同一 network 里。

参数说明:--appendonly yes开启 AOF 持久化,--replicaof指定主节点地址和端口,depends_on只保证启动顺序,不保证主节点完全就绪,生产环境需要在应用层做重试。

5. 避坑与排查:离线装 docker 最常翻车的五个地方

5.1 现象:dockerd 启动报failed to start daemon: error initializing graphdriver: overlay2 not supported

原因:内核版本过低或 overlay 模块未加载。CentOS 7 默认内核 3.10 支持 overlay2,但某些裁剪版系统把模块去掉了。

解决:先lsmod | grep overlay确认模块是否存在,没有就modprobe overlay。如果模块不存在,需要升级内核或换devicemapper存储驱动(不推荐,性能差)。在/etc/docker/daemon.json里显式指定{"storage-driver": "overlay2"}并重启 docker。

5.2 现象:docker-compose up报ERROR: Version in "./docker-compose.yml" is unsupported

原因:compose 文件里写的version: "3.8"和你装的 docker-compose 版本不匹配。v2.20 以下对某些版本号解析有问题。

解决:要么升级 docker-compose 到 v2.20+,要么把 compose 文件里的version字段删掉。从 compose 规范 v2 开始,version字段已经被标记为 obsolete,删掉不影响功能。

5.3 现象:容器内无法解析域名,ping baidu.com报unknown host

原因:离线环境没有配置 DNS,docker 默认用宿主机的/etc/resolv.conf,如果宿主机本身没配 DNS,容器里也没有。

解决:在/etc/docker/daemon.json里加{"dns": ["114.114.114.114", "8.8.8.8"]},然后systemctl restart docker。如果内网有 DNS 服务器,换成内网地址。注意这个配置对已运行的容器不生效,需要重建容器。

5.4 现象:docker load导入镜像后docker images看不到

原因:导入的 tar 包不是docker save生成的,可能是ctr或skopeo导出的格式,docker 不认。

解决:用docker load -i xxx.tar时加-i参数明确指定输入文件,观察输出里有没有Loaded image:字样。如果没有,用tar -tf xxx.tar看包内结构,正常的 docker save 包第一层是manifest.json和若干层目录。格式不对就用skopeo copy转一道。

5.5 现象:systemctl start docker卡住不返回,超时后失败

原因:docker 启动时要初始化 iptables 规则,如果宿主机 iptables 规则特别多或者有冲突,会卡很久。

解决:先systemctl stop docker,然后手动执行/usr/bin/dockerd --debug看卡在哪一步。常见的是iptables链被其他软件(如 firewalld、kube-proxy)改乱了。临时方案是在 daemon.json 里加{"iptables": false},但这样容器就没有端口映射的 NAT 规则了,只适合纯 host 网络场景。根治方法是清理 iptables 规则后重启 docker。

6. 把安装包做成可复用交付物:校验、版本锁定和升级回滚

6.1 打包成一个自解压安装脚本

每次交付都手动敲一遍命令太累,我习惯把二进制包和安装脚本打在一起。目录结构如下:

docker-offline-installer/ ├── packages/ │ ├── docker-26.1.4.tgz │ └── docker-compose-linux-x86_64 ├── systemd/ │ ├── docker.service │ └── containerd.service ├── install.sh └── SHA256SUMS

install.sh的核心逻辑:

#!/bin/bash set -e # 校验安装包完整性 sha256sum -c SHA256SUMS # 解压 docker 二进制 tar -xzf packages/docker-26.1.4.tgz -C /tmp/ # 拷贝二进制 cp /tmp/docker/* /usr/bin/ chmod +x /usr/bin/docker* /usr/bin/containerd* /usr/bin/ctr /usr/bin/runc # 安装 docker-compose cp packages/docker-compose-linux-x86_64 /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose # 安装 systemd 单元 cp systemd/docker.service /etc/systemd/system/ cp systemd/containerd.service /etc/systemd/system/ # 启动服务 systemctl daemon-reload systemctl enable --now containerd systemctl enable --now docker # 输出验证信息 docker --version docker-compose --version docker info | grep -E "Server Version|Storage Driver"

set -e让脚本在任何一步失败时立即退出,避免半装状态。sha256sum -c校验失败会返回非零,同样触发退出。

6.2 版本锁定与升级回滚

离线环境最怕的是「装完能用,但不知道装的是哪个版本,下次想升级或回滚找不到包」。我的做法是在交付物里放一个VERSIONS文件,记录每个组件的版本号和 SHA256。

升级时,先systemctl stop docker,然后用新版本的二进制覆盖/usr/bin/下的文件,再systemctl start docker。回滚同理,把旧版本二进制拷回来即可。注意 containerd 和 runc 的版本要和 docker engine 匹配,不要单独升级其中一个。

提示:升级前用docker save把关键镜像导出备份,虽然升级 docker 本身不会丢镜像,但存储驱动变更可能导致镜像不可用。

6.3 验证清单:装完必须确认的五个点

检查项命令期望结果
docker 客户端docker --version输出版本号
docker 服务端docker infoServer Version 有值
存储驱动docker info | grep Storageoverlay2
compose 版本docker-compose --versionv2.20+
容器网络docker run --rm alpine ping -c 1 8.8.8.8能通(需有镜像)

最后一条如果没有 alpine 镜像,可以跳过,但网络验证建议用docker network create test-net && docker network inspect test-net确认 bridge 网络创建正常。

6.4 一个我反复用的技巧:用docker-compose config做语法预检

在离线环境里,compose 文件写错了要等up的时候才报错,浪费时间。我习惯先跑:

# 只解析和校验 compose 文件,不实际启动容器 docker-compose -f docker-compose-redis.yml config

这条命令会把最终生效的配置打印出来,包括环境变量替换、默认值填充的结果。如果 YAML 语法有问题或者引用了不存在的变量,这里就会报错。确认无误再up -d,能省掉很多来回。

我自己的习惯是:每次交付前,在测试机上用同样的安装脚本跑一遍,把docker info和docker-compose config的输出截图存档。到了现场如果出问题,直接对比输出差异,比盲猜快得多。这套离线安装包方案我用了三年多,从 CentOS 7 到 Ubuntu 22.04,从物理机到虚拟机,没换过核心思路——静态二进制加 systemd 托管,简单、可控、可回滚。希望帮到你。

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询