news 2026/10/8 2:51:20

arm64 openEuler 离线安装 Docker 与 Docker-Compose 完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
arm64 openEuler 离线安装 Docker 与 Docker-Compose 完整指南

简介:面向arm64架构服务器上的Docker离线部署场景,该安装包内置Docker与Docker Compose组件,并附带一键安装脚本,已在openEuler操作系统下完成验证,适合内网或无外网环境中快速搭建容器环境的运维人员、测试工程师及开发者使用。压缩包共4个文件,包括Docker安装tgz包、systemd服务文件、安装脚本和docker-compose可执行文件,整体大小为54.41MB,结构简洁,部署时只需解压上传并执行安装脚本即可完成Docker安装,再将docker-compose拷贝至系统目录并赋权即可直接调用。相比在线安装方式,该方案规避了网络限制,也减少了版本不一致带来的兼容问题。目前已有645人学习/下载,可用于生产或测试环境初始化、批量部署及离线项目交付,也可配合作者发布的在线安装与卸载教程对比学习,是一套经过实际验证、可直接落地的arm64离线部署工具包。

1. arm64 离线装 Docker 与 Docker-Compose:openEuler 上别照搬 x86 教程

拿到一台 arm64 架构、纯内网环境的 openEuler 服务器,你的第一反应大概率是上网搜 docker 安装教程,照着 yum 一把梭。但真这么干,你会发现要么仓库连不上,要么装完 docker 服务起不来,日志里报一堆 overlay 和依赖错误——因为网上绝大多数教程都是 x86 架构、Ubuntu 或 CentOS 的,照搬到 arm64 + openEuler 上,每一步都可能踩坑。这份在 openEuler 上验证过的 arm64 平台 docker 和 docker-compose 离线安装包,就是把整个安装链路的依赖包、配置文件和验证步骤全部固化下来,自带一键安装脚本,专门解决内网、信创、断网环境下的交付问题。适合离线交付实施、需要快速复现 docker 环境的运维,以及不想在依赖解析上浪费时间的一线工程师。

2. 拆解离线安装包:目录、依赖与一键脚本的工作逻辑

2.1 包内有什么:目录结构与文件清单

拿到手先别急着跑脚本,花两分钟把目录结构看清。这类离线包的组织方式大同小异,常见布局如下:

docker-offline-arm64/ ├── README.md ├── install.sh ├── uninstall.sh ├── docker/ │ ├── docker-ce.rpm │ ├── docker-ce-cli.rpm │ ├── containerd.io.rpm │ ├── docker-compose-plugin.rpm │ └── ... 其他依赖 rpm ├── compose/ │ └── docker-compose └── images/ ├── mysql-8.0-arm64.tar ├── redis-7-arm64.tar └── nginx-1.24-arm64.tar

这里最容易被忽略的是根目录的README.md,它会写明这次打包用的 openEuler 版本、docker engine 和 compose 的版本号,以及验证环境的架构信息。我习惯拿到包第一件事是cat README.md,确认发布环境跟目标机一致,再看install.sh的内容。

docker/目录里放的是 rpm 包,用 rpm 方式而不是 tar 二进制,是因为 openEuler 的 systemd 集成、启动脚本、目录规范都是围绕 rpm 来的,用 rpm 装完systemctl start docker就能直接拉起服务,不用手工铺可执行文件和配置 unit 文件。compose/下只有一个docker-compose独立二进制,这是新版 docker-compose 的常见做法,跟 docker engine 解耦,方便单独升级。images/放的是预导出的镜像 tar,属于可选内容,我后面单独讲。

2.2 为什么 arm64 的 docker 必须单独准备包

docker engine 本身就是编译产物,不同 CPU 架构对应的二进制完全不同。arm64 和 amd64 的 rpm 包虽然都叫docker-ce,但安装时依赖的containerd.io、runc、libseccomp都有对应架构的版本,混用会出现两类问题:一是yum install时依赖解析失败,提示找不到兼容的依赖包;二是包能装上,但 docker daemon 启动后拉取的镜像架构不对,跑容器报exec format error。

openEuler 跟 CentOS 虽然都是 rpm 系,但基础库和内核配置有差异。比如 openEuler 在 overlay 存储驱动上遇到过内核模块未加载的问题,导致 docker 数据目录初始化失败。这套离线包在 openEuler 上验证过,意味着它已经把这个链路里所有可能的阻碍都处理掉了——包括哪些 rpm 是必需依赖、哪些包之间的版本要互相匹配、启动服务前要不要加载特定内核模块。

从网络热搜里能看到大量装机到一半翻车的案例,比如docker desktop failed to start because virtualisation support wasn't detected,或者permission denied while trying to connect to the docker api。这些在服务器环境下都不适用,但反映出一个共性问题:docker 安装的失败点往往不在 docker 本身,而在系统环境。arm64 + openEuler 的组合,照着官方文档装经常会碰到仓库源里没有 openEuler 专属的 rpm 包,只能去 CentOS 源里找兼容包,摸不清依赖关系的话,很容易陷入装一个报一个的循环。

2.3 一键脚本的设计目标

install.sh的存在价值是,把人工操作从十几条命令收敛成一次执行。脚本内部通常要完成这几件事:检查当前机器架构是否为 aarch64、检查是否为 openEuler 系统、安装目录下的所有 rpm 包、把docker-compose放到/usr/local/bin并加执行权限、启动 docker 服务、设置开机自启、最后输出版本信息作为安装完成的标志。

脚本里会写死一个架构判断,防止有人误把 x86 的包拷到 arm64 机器上执行。这个判断很关键,因为离线交付经常是运维同事带着 U 盘拷包,出错的概率很大。如果脚本开头没有uname -m检查,后面的 rpm 安装会在中途依赖解析失败报错,但那时你已经不知道是包不对还是环境不对了。

脚本的返回码设计也有讲究。正常执行完会输出Docker installed successfully和两个版本号,如果中途失败,脚本会直接退出并带上非 0 的退出码,方便你在交付单上记录失败节点。我不会把脚本设计成遇到错误继续往下跑的类型,那会让问题更难排查。

3. 手工复现完整离线安装:从系统检查到 docker compose 跑通

3.1 先做系统检查:架构、系统版本、磁盘

即便有一键脚本,我还是建议亲手跑一遍完整流程,这样出问题时知道是哪个环节挂的。以下是一个标准的复现流程,你也可以把它当作交付前的验证清单。

# 确认 CPU 架构,aarch64 表示 arm64 架构 uname -m # 确认系统版本 cat /etc/openEuler-release # 确认内核版本,docker 对内核版本有最低要求 uname -r # 查看 /var/lib/docker 所在分区的剩余空间 df -h /var/lib

第一行输出必须是aarch64,如果是x86_64,直接停,包拿错了。第二行看 openEuler 的具体版本号,20.03 LTS 和 22.03 LTS 的包管理差异不小,确认它跟离线包 README 里写的一致。第三行看内核版本,docker 在 openEuler 上一般要求内核 4.19 以上,openEuler LTS 默认内核都满足,但如果你跑的是裁剪过的内核,就要注意 overlay 模块是否存在。最后一行的磁盘检查最容易被忽略,/var/lib/docker是 docker 的默认数据目录,镜像和容器层都往这里写,空间不够后面导入镜像时会报no space left on device。

以上四条命令都不需要联网,也不会改变系统状态,适合在正式操作前先跑一遍。检查通过后,再开始执行安装。

3.2 安装 docker engine:rpm 包安装顺序与依赖

openEuler 默认用 dnf 做包管理,离线环境下没有可用仓库,所以这里不能裸跑dnf install,一般有两条路:直接用rpm命令逐个安装,或者用dnf指定本地目录作为临时 repo。

# 进入 rpm 包所在目录 cd docker/ # 一次性安装所有 rpm,自动处理包间依赖 rpm -ivh *.rpm --nodeps --force

这里我要特别说明:--nodeps --force这种写法在离线场景下是可行的,因为离线包内的 rpm 已经经过完整的依赖验证,所谓"跳过依赖检查"只是为了让 rpm 不额外去解析系统中不存在的依赖。但如果你不确定包内依赖是否完整,就不要加--nodeps,让它老老实实报错,反而能提前发现问题。

包与包之间有依赖顺序,runc和containerd.io要先于docker-ce就位。rpm -ivh *.rpm会把文件名排序后依次安装,如果顺序不对,先后关系并不影响最终结果,因为 rpm 会在当前已经安装的包中解析依赖。唯一需要注意的是,如果之前装过旧版 docker,先卸载干净再装,否则rpm -Uvh会报文件冲突。

3.3 安装 docker-compose:二进制复制与验证

新版 docker-compose 已经不依赖 python,直接给一个独立二进制就行。相比用 pip 或 dnf 装,二进制方式的好处是干净、无依赖、版本可控。

# 把 docker-compose 复制到系统 PATH 目录 cp compose/docker-compose /usr/local/bin/docker-compose # 给执行权限 chmod +x /usr/local/bin/docker-compose # 验证版本 docker-compose version

复制之后先chmod +x,这个不用提醒你也会做。真正要验证的是执行权限之外的东西——架构。docker-compose version能正常输出版本号,说明这个二进制在当前架构下是可执行的。如果提示Exec format error,说明你拿到的是 x86 版,跟第 4 章讲的镜像架构问题同源。

新版 docker 还支持直接用docker compose(无连字符)作为子命令,前提是安装了docker-compose-plugin这个 rpm。离线包里如果带了这个插件,两条命令都能用;如果只有独立的docker-compose二进制,那docker-compose命令可用,而docker compose子命令会提示找不到。我一般建议两个都支持,因为现在很多 compose 配置文件的说明文档里两种写法混着来。

3.4 启动 docker 并验证安装结果

rpm 安装完成后加启动服务,这一段的顺序不要倒过来。先把开机自启配置好,再启动服务,避免在启动后还没写 systemd 配置时就被其他操作中断。

# 设置开机自启 systemctl enable docker # 启动 docker 服务 systemctl start docker # 查看服务状态 systemctl status docker # 输出 docker 版本、架构、存储驱动等关键信息 docker info

docker info输出里重点看两个字段:Architecture如果是aarch64,说明 daemon 跑在 arm64 上;Server Version是 docker engine 的版本号,跟 README 里声明的一致。另外看Storage Driver,正常情况下是overlay2,如果显示vfs说明内核 overlay 模块没加载,能用但性能差很多,建议回到第 4 章排查。

最后做一次最小验证,跑一个本地容器确认整个链路通:

# 如果有本地镜像,直接 run 一个 docker run --rm 本地镜像名:tag /bin/echo "docker ok"

这个容器跑完自动退出并删除,不会留下残留。如果你的images/目录里带了镜像 tar,先导入再验证;如果没带,可以暂时跳过这一步,等后续有镜像源再验证。上面这套流程我给它起名叫"install check",每次离线交付前路径不同,但流程不变。

4. 避坑:arm64 openEuler 离线安装的五个典型故障与排查

4.1 docker 服务启动即退出,日志报 overlay 存储驱动错误

现象:systemctl start docker执行后,systemctl status docker显示 active (failed),用journalctl -u docker看日志,报error initializing graphdriver: operation not permitted或failed to mount overlay。

原因:openEuler 默认可能没有加载 overlay 内核模块,常见于最小化安装或裁剪内核的环境。docker 默认首选 overlay2 存储驱动,找不到模块就初始化失败。

解决:先手动加载模块再重启 docker。

modprobe overlay lsmod | grep overlay systemctl restart docker

如果modprobe报模块不存在,说明内核没编这个模块,只能降级把存储驱动改成 vfs。在/etc/docker/daemon.json里写{"storage-driver": "vfs"},重启 docker。vfs 慢,但能跑起来。

4.2 docker-compose 执行报 Exec format error

现象:docker-compose version输出Exec format error,或者直接Permission denied(确认 chmod 之后问题不在权限)。

原因:拿到的docker-compose是 amd64 编译的二进制,放到 arm64 机器上执行,内核不认识这个指令集。这类问题在从网盘下载文件时经常发生,因为网页默认给的下载链接可能是 x86 版的。

解决:用file命令确认二进制架构,这是我在 arm64 机器上执行带编译型二进制之前必做的一步。

file /usr/local/bin/docker-compose # 期待输出 aarch64, 而不是 x86-64

如果确实是架构不符,只能重新获取 arm64 版的 docker-compose,注意检查下载时选中的 platform 标记。另外,docker compose插件方式的架构错误会通过 rpm 安装时由系统直接拦截,很少出现这个报错。

4.3 有镜像却跑不起来:容器启动报 exec format error

现象:离线导入镜像后,docker images能看到镜像,docker run却报exec format error,或者直接说failed to create shim task。

原因:镜像 tar 是从 x86 机器上docker save出来的,里面是 amd64 的镜像层。arm64 的 docker 只能加载镜像元数据,真正运行时就暴露了架构不兼容。

解决:导入前先检查镜像架构。

# 导入镜像 tar docker load -i mysql-8.0-arm64.tar # 查看镜像架构 docker image inspect mysql:8.0 --format='{{.Architecture}}'

输出必须是arm64或aarch64,如果是amd64,这个镜像在这个环境里跑不了,需要去 arm64 的仓库重新拉取镜像再 save。这里的血泪经验是:离线交付的完整闭环不只是"docker 能启动",还包括"目标镜像能在目标架构上跑起来"。我每次交付前都会把镜像架构检查写进交付清单。

4.4 容器端口访问不了:firewalld 与 SELinux 双重拦截

现象:docker ps正常,容器也在运行,但在宿主机上curl http://localhost:8080不通,业务方反馈端口开了却没反应。

原因:openEuler 默认启用了 firewalld,容器映射到宿主机的端口没有放行;另外 SELinux 开启的情况下,容器进程的网络访问也可能被拦。

解决:先放行端口,再处理 SELinux。

# 放行容器映射的端口 firewall-cmd --add-port=8080/tcp --permanent firewall-cmd --reload # 临时把 SELinux 设为宽松模式,测试是否为拦截原因 setenforce 0

如果setenforce 0后容器立即通了,说明是 SELinux 策略问题。可以长期开启容器的 SELinux nezha 配置,或者在/etc/selinux/config里按业务要求处理。但注意,服务器安全策略不该由运维单方面决定,涉及生产环境要跟安全确认后再动。

4.5 离线 yum 安装时依赖解析失败或卡在等待

现象:dnf install docker/*.rpm报Could not resolve host,或者长时间卡在Downloading,再怎么等都没结果。

原因:离线环境没有配置本地 dnf 仓库,系统默认的 repo 指向公网,网络不通导致 dnf 直接挂起。有人会改用rpm -ivh绕开仓库解析,但如果 rpm 包本身就依赖系统中未装的库(比如libseccomp版本过低),还是会失败。

解决:优先用rpm -ivh并配合--nodb场景检查依赖,或者临时禁用所有仓库。

# 安装时禁用所有仓库,避免网络等待 rpm -ivh docker/*.rpm --nodeps

离线包内的 rpm 如果是从 openEuler 同版本环境里收集出来的完整依赖集,--nodeps是安全操作。如果是从网上下载的散装 rpm,就不要加--nodeps,让 rpm 告诉你缺哪个库,然后去docker/目录里翻有没有对应包。盲猜依赖是离线安装里最浪费时间的事情,不如让 rpm 一次性列全。

5. 把一键脚本拆开看:参数、修改点与卸载清理

5.1 脚本执行流程与关键判断逻辑

install.sh核心逻辑可以概括成几个阶段,每个阶段对应一个函数或一段独立的命令块。下面这个片段可以作为理解脚本结构的最小参考,实际包里的脚本可能加了更多日志,但骨架一致:

#!/bin/bash set -e # 阶段 1:前置检查,不满足条件就直接退出 ARCH=$(uname -m) if [ "$ARCH" != "aarch64" ]; then echo "当前架构不是 aarch64,请确认离线包与目标机匹配" exit 1 fi # 阶段 2:安装 rpm 包,忽略 repo 网络等待 rpm -ivh docker/*.rpm --nodeps # 阶段 3:安装 docker-compose 二进制 install -m 755 compose/docker-compose /usr/local/bin/docker-compose # 阶段 4:启动并设置开机自启 systemctl daemon-reload systemctl enable docker systemctl start docker # 阶段 5:验证 docker info docker-compose version echo "Docker offline install completed."

脚本开头set -e的语义是,任何一条命令失败就立即退出整个脚本,不继续往下执行。这个设计在安装场景下是对的,因为你不需要保留"装了一半"的状态。如果你要改脚本,注意保持这个行为,不要为了让脚本"看起来很顺利"而用|| true把错误吞掉。

我用install -m 755而不是cp加chmod,是因为它是原子操作,目标文件直接带上可执行权限,少一步人工操作,也避免了中间状态。

5.2 常用参数与自定义修改点

实际使用时,最常见的需求是改 docker 数据目录。默认/var/lib/docker如果空间不够,你需要把数据目录挪到大分区。脚本本身不会帮你做这一步,但你可以在执行安装前先修改 docker 的启动配置:

# 创建自定义数据目录 mkdir -p /data/docker # 编辑 daemon.json cat > /etc/docker/daemon.json <<EOF { "data-root": "/data/docker", "storage-driver": "overlay2" } EOF

这段配置要写在脚本执行前,因为它会导致一个新问题:如果 docker 服务已经启动过、数据目录里已经有了内容,再改># 1. 停止 docker 服务并禁止开机自启 systemctl stop docker systemctl disable docker # 2. 卸载相关 rpm 包 rpm -qa | grep docker rpm -e docker-ce docker-ce-cli containerd.io runc # 3. 删除数据目录和配置 rm -rf /var/lib/docker rm -f /etc/docker/daemon.json rm -f /usr/local/bin/docker-compose

rpm -qa | grep docker先列出已安装的 docker 相关包,再逐个卸载。卸载顺序跟安装顺序相反,先卸 docker-ce 再卸 containerd.io 和 runc,是因为 docker-ce 依赖后两者,如果先卸底层包,rpm 会提示依赖关系报错。/etc/docker/daemon.json是配置文件,不删的话,下次重装 docker 会自动读这个旧配置,可能带上已不存在的># 在能联网的 arm64 机器上拉取镜像并导出 docker pull mysql:8.0 docker save mysql:8.0 -o mysql-8.0-arm64.tar # 在目标离线机器上导入 docker load -i mysql-8.0-arm64.tar

这里的关键点是docker pull必须发生在相同架构的机器上。如果拿 x86 开发机拉 mysql 镜像再 save,拷到 arm64 上 load 能成功,但一docker run就会报第 4 章里的 exec format error。 我一般会在下载镜像的机器上先跑一次docker image inspect确认架构,再开始打 tar 包,这一步能省掉后面整个交付现场的排查时间。

6.2 常见镜像的离线交付验证

镜像 load 进去之后,不要急着说"装好了"。用容器实际启动一次,确认业务可用,才算闭环。下面是一个针对 mysql 的快速验证:

# 启动一个测试容器,验证镜像可运行 docker run -d --name test-mysql \ -e MYSQL_ROOT_PASSWORD=test123456 \ -p 3306:3306 mysql:8.0 # 等待初始化完成后检查日志 docker logs test-mysql | tail -20 # 确认端口监听 ss -tlnp | grep 3306

容器能启动、日志没有报错、宿主机端口在监听,这三个条件同时满足,这个镜像才算真正可用。对于复杂应用,比如码云那个开源网盘 kodbox、gitlab 或青龙面板这类依赖多个环境的容器编排项目,建议直接使用docker-compose up -d来验证,它会把网络、卷、依赖关系全部串起来。在 arm64 + openEuler 这个组合下,很多镜像在 x86 上跑得好好的,换了架构会出现各种奇怪问题,比如 qemu 模拟、arm64 镜像 magic 字串不对之类的报错。所以每次离线交付,我都把"在目标架构上真实启动一次容器"列为必做项,绝不只到docker load成功为止。从那以后,我每次做离线交付,哪怕赶时间也强制走一遍"架构确认 → save/load → run 验证"三步流程,确认无误才在交付单上签字。这套方法希望帮到你,让你在 arm64 的 openEuler 上少花几个晚上。

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/8 2:51:20

华为S12700E交换机ACL与QoS硬件资源深度解析

简介&#xff1a;本资源是华为CloudEngine S12700E系列交换机的官方产品详解文档&#xff0c;面向网络工程师、园区网规划人员及ICT解决方案架构师&#xff0c;聚焦现代智慧园区场景下对高带宽、低时延、大容量与高可靠性的核心诉求。文档系统解析S12700E-4/8/12三款机型的硬件…

作者头像 李华
网站建设 2026/10/8 2:50:57

Livox Avia与FAST-LIO2激光惯性SLAM建图实操教程

我陆续见过不下二十个拿着Livox Avia的初学者&#xff0c;卡在FAST-LIO2这个组合上&#xff0c;问题都差不多&#xff1a;环境装不明白、launch文件不知道改哪个、外参乱填一通、跑起来地图像揉皱了的纸。索性这次我用一篇“麻瓜也能照抄”的教程&#xff0c;把从装系统到拿到一…

作者头像 李华
网站建设 2026/10/8 2:50:18

SpringBoot+Vue+MySQL扶贫助农系统毕设源码与部署全攻略

1. 项目背景与总体定位网上关于实验室管理系统、商城系统、管理后台的毕设源码一抓一大把&#xff0c;但真正贴合“扶贫助农”这个业务场景、又能完整跑通“前端展示后端管理数据落库文档交付”的SpringBootVueMySQL项目&#xff0c;其实并不多。大多数同学拿到手的版本要么只有…

作者头像 李华
网站建设 2026/10/8 2:49:57

博科DCX-4S配置维护与固件升级实战指南

简介&#xff1a;这份博科DCX-4S光纤交换机配置维护升级手册面向存储网络运维工程师、数据中心SAN管理员及备考相关认证的技术人员&#xff0c;针对DCX-4S在ZONE划分、配置备份、日常巡检与微码升级等环节缺少系统中文指引的问题&#xff0c;提供一份完整版操作参考。资源包共1…

作者头像 李华
网站建设 2026/10/8 2:49:19

Git与GitHub入门:SSH配置与克隆仓库避坑指南

你是不是也遇到过这种情况&#xff1a;在 GitHub 仓库页面上点开 Clone 按钮&#xff0c;看到 HTTPS 和 SSH 两个选项&#xff0c;习惯性复制了 HTTPS 链接&#xff0c;结果每次 push 都要输用户名密码&#xff0c;一不小心还提示认证失败&#xff1b;或者明明照着网上的教程生…

作者头像 李华