☰
ARM64离线部署Tengine 3.1.0:Docker-Compose一键交付方案
2026/10/1 5:18:25 网站建设 项目流程

简介:面向ARM64架构CPU的Tengine 3.1.0离线部署工具包,专为内网或离线环境的运维场景打造。借助docker-compose编排,可实现“一键式”快速部署,并支持灵活修改配置文件,使配置、日志及静态资源目录得以持久化保存,适用需要快速交付Web服务的ARM服务器环境。整套工具包共包含14个文件,主要由conf站点配置、gz离线资源包、html静态页面、sh构建脚本、yml编排文件及dockerfile镜像定义等组成,整体体积34.54MB,结构清晰便于按需调整。其中gz压缩包涵盖tengine-3.1.0-arm64及alpine基础镜像等离线依赖,conf目录预置默认站点与证书配置示例,sh和yml分别完成镜像构建与容器启停操作。目前已有101人学习使用,对希望在内网环境快速落地Tengine的运维工程师或架构师而言,这套打包好的方案可直接复用,节省镜像拉取与依赖处理成本,也便于后续二次定制。

1. 离线部署 Tengine 3.1.0 到 ARM64 主机:这套方案解决什么问题

国产化替代和内网隔离两座山压下来,ARM64 服务器上离线跑 Web 服务成了交付工程师躲不开的活。标题里这条「基于 ARM64 架构 CPU 使用 docker-compose 一键离线部署 tengine 3.1.0」的路线,本质是把阿里开源的 Nginx 增强版 Tengine 3.1.0 做成容器镜像,再用离线镜像文件加 compose 编排,在内网机器上一条命令拉起。它能解决三件具体的事:不在 ARM64 机器上现场编译 Tengine,告别依赖地狱;把镜像、配置、启动脚本收敛成一个可交付目录,换一台机器重复执行同样结果;把一天的手工排错压缩成一次 load 加一次 up。适合正在做信创适配、需要往客户内网反复交付 Web 服务的运维和实施。先把丑话说在前面:这套方案真正的门槛不在 compose 文件本身,而在离线依赖完整性和架构匹配,这两件事做在前面,后面全是顺水推舟。

2. 确认 ARM64 环境、拉取 Tengine 镜像与离线依赖清单:动手前的三件事

离线部署最怕做到一半发现环境不对。按下键盘之前,先把目标机器的架构、镜像的架构、compose 工具的来源三件事确认完,后面才不会翻车。

2.1 分清“真 ARM64”和 QEMU 模拟的 ARM64:uname、lscpu 与 docker 三处对照

ARM64 和 x64 有什么区别,落到部署上就一句话:指令集不同,容器镜像不通用。x86_64 上 build 的镜像拿到 ARM64 机器上直接起不来,反过来也一样。所以第一步不是写 compose,而是确认目标机到底是什么。

# 1. 看内核架构 uname -m # aarch64 是真 ARM64;x86_64 就是 x64 # 2. 看 CPU 详细信息 lscpu | grep -E 'Architecture|型号名称|Model name' # 3. 看 docker 服务端所在系统架构 docker version --format '{{.Server.Arch}}'

逐条说:uname -m是内核报告的机器架构,aarch64就是 ARM64 的 Linux 命名;docker version里 Server.Arch 告诉你 docker daemon 跑在什么架构上,这个值和客户端无关,容器最终由 daemon 执行,所以它才是权威。有交付现场拿 x86 机器开 QEMU 模拟 arm64 环境来验收,这种环境里uname -m也会显示 aarch64,但性能和系统调用行为跟真机有差异,容器网络、io_uring 这类特性可能表现不同。我的判断标准是:验收和最终上线必须在同一类真机上做,QEMU 环境只用来验证配置语法,不拿来验证性能。

docker 平台写法里的linux/arm64/v8对应安卓生态常说的 arm64-v8a,都是 armv8 指令集,只是命名体系不同,选镜像时看到这几个写法可以互相印证。

2.2 在联网中转机拉取并导出 Tengine 3.1.0 镜像:save 前先验架构

离线部署的镜像来源通常是一台能联网的中转机,把镜像 pull 下来、确认架构、再导出成 tar 带走。Tengine 3.1.0 的镜像源以你内网可信的仓库为准,这里用tengine:3.1.0作占位,实际地址按你的来源填。

# 中转机上执行 docker pull tengine:3.1.0 # 导出之前先验架构,这是最容易被跳过的一步 docker inspect tengine:3.1.0 --format '镜像架构:{{.Architecture}} 系统:{{.Os}}' # 期望输出: 镜像架构:arm64 系统:linux # 确认无误后导出 docker save tengine:3.1.0 -o tengine-3.1.0-arm64.tar # 顺手算个校验值,传输后用来验证文件没坏 sha256sum tengine-3.1.0-arm64.tar > tengine-3.1.0-arm64.tar.sha256

逻辑说明:docker save是把镜像完整导出为 tar,包含所有层和元数据;docker inspect的.Architecture字段是镜像构建时声明的目标架构,不是当前主机的架构,所以它能在 pull 之后立刻告诉你这份镜像能不能在 ARM64 上跑。sha256sum生成校验文件属于习惯动作,内网传输用 U 盘或者 scp 都可能丢位,有了校验文件,到目标机上sha256sum -c一下就能确认没坏。

一个容易被忽略的细节:如果镜像仓库做了多架构 manifest,在 x86 中转机上docker pull默认拉到的是 amd64 版本,导出带走照样跑不起来。想直接看远程仓库里有哪些架构,用docker buildx imagetools inspect <镜像地址>可以列出所有平台,比盲目 pull 再 inspect 更早发现风险。

2.3 离线环境补 docker-compose:二进制、plugin 包与版本匹配

镜像只是第一份离线依赖,docker-compose 本身同样需要离线安装。目标机如果是麒麟 v10 ARM64(Debian 系),可以直接在中转机上下载对应架构的 deb 包装进去;如果 docker 是标准安装,也可以下载 compose 独立二进制。

# 中转机下载 docker-compose 2.32.1 的 linux aarch64 版 # 官方 release 资产命名规则: docker-compose-linux-aarch64 wget https://github.com/docker/compose/releases/download/v2.32.1/docker-compose-linux-aarch64 -O docker-compose chmod +x docker-compose # 拷贝到目标机后放到 PATH 下 sudo mv docker-compose /usr/local/bin/ docker-compose --version

注意区分两个命令形态:docker-compose(带横线)是独立二进制,v1 和 v2 都有这种形态;docker compose(带空格)是 docker 的插件,v2 主推这种形态。很多机器上只装了一个,脚本里要兼容两者,后面第 5 章会专门讲这里踩的坑。离线现场最省事的做法是我一般让交付包里直接带上对应架构的 compose 二进制,和镜像 tar 放一起,到现场mv到/usr/local/bin就完事,不赌目标机预装了什么。

提示:compose 版本和 docker 版本有兼容关系,2.x 的 compose 需要 docker 20.10 以上。目标机 docker 版本太老时,优先选和它匹配的 compose 老版本,不要一味追新。

3. 编写 docker-compose.yml 与 deploy.sh 一键脚本:从 load 镜像到拉起服务

离线部署的“一键”不是真的只敲一条命令,而是把 load、校验、拉起、探活四件事串进一个脚本,让现场操作的人只需要执行一次。这一章把 compose 文件和脚本拆开讲,每一行都能照着改。

3.1 docker-compose.yml 字段设定:端口、卷、重启策略与日志上限

Tengine 3.1.0 的配置路径沿用 Nginx 习惯,一般镜像默认是/etc/nginx/nginx.conf,个别源码编译的镜像会装在/usr/local/nginx/conf。先按/etc/nginx写,挂载前用docker exec进容器确认一次路径即可。

services: tengine: image: tengine:3.1.0 container_name: tengine-310 restart: always ports: - "80:80" - "443:443" volumes: - ./conf/nginx.conf:/etc/nginx/nginx.conf:ro - ./conf/conf.d:/etc/nginx/conf.d:ro - ./html:/usr/share/nginx/html:ro - ./logs:/var/log/nginx environment: - TZ=Asia/Shanghai logging: driver: json-file options: max-size: "50m" max-file: "3"

参数逐个说:image的 tag 必须和docker load进本机的 tag 完全一致,否则 compose 会去远程仓库拉取导致离线失败;restart: always保证宿主机重启后容器自动拉起,内网交付没有人在现场盯着,这是刚需;ports里"80:80"是宿主机端口:容器端口,宿主机 80 被占时改成"8080:80"即可;volumes用相对路径挂载,compose 会以 yml 所在目录为基准创建相对路径目录,ro表示只读,配置和静态文件不允许容器内改动;logs目录不要只读,nginx 的 access.log 和 error.log 要写入。日志 json-file 限制大小是防长期运行把磁盘写满的后悔药。

3.2 deploy.sh 一键脚本:架构检查、load 镜像、compose up、探活

脚本的作用是把上一章的准备工作固化成自动检查,任何人拿到交付包执行./deploy.sh都能得到同样结果。

#!/usr/bin/env bash set -euo pipefail # 1. 主机架构检查: 只允许 ARM64 ARCH=$(uname -m) case "$ARCH" in aarch64|arm64) ;; *) echo "仅支持 ARM64 主机, 当前架构: $ARCH"; exit 1 ;; esac # 2. docker 与 compose 存在性检查 command -v docker >/dev/null 2>&1 || { echo "缺少 docker, 先安装"; exit 1; } if ! command -v docker-compose >/dev/null 2>&1 && ! docker compose version >/dev/null 2>&1; then echo "缺少 docker-compose, 请先离线安装"; exit 1 fi # 3. 镜像不存在时自动 load IMG="tengine:3.1.0" if ! docker image inspect "$IMG" >/dev/null 2>&1; then echo "加载离线镜像 tengine-3.1.0-arm64.tar ..." docker load -i tengine-3.1.0-arm64.tar fi # 4. 再验一次镜像架构, 防止交付包拿错 IMAGE_ARCH=$(docker image inspect "$IMG" --format '{{.Architecture}}') if [ "$IMAGE_ARCH" != "arm64" ] && [ "$IMAGE_ARCH" != "aarch64" ]; then echo "镜像架构 ${IMAGE_ARCH} 与主机不匹配, 请换 arm64 镜像包"; exit 1 fi # 5. 拉起服务 docker compose up -d # 6. 探活: 最多等 20 秒 for i in $(seq 1 10); do if curl -sf -o /dev/null http://127.0.0.1/; then echo "Tengine 3.1.0 已就绪" exit 0 fi sleep 2 done echo "服务未响应, 执行 docker logs tengine-310 查看原因" exit 1

脚本逻辑说明:set -euo pipefail让任何一步失败立即退出,避免现场人员看着半截成功当全成功;第 3 步用docker image inspect判断镜像是否已存在,存在就跳过 load,所以脚本重复执行也是安全的;第 4 步把第 2 章的架构检查内置进来,防止交付包在打包时拿错架构;第 6 步的探活循环里,宿主机必须有 curl,如果没有可以换wget -q --spider http://127.0.0.1/。注意脚本里的docker compose up -d用的是 v2 插件形态,如果你的现场只有 v1 独立二进制,把这一行换成docker-compose up -d。

3.3 配置文件挂载方式:nginx.conf 与 conf.d 的离线改法

Tengine 3.1.0 的配置和 Nginx 基本通读,主配置里include /etc/nginx/conf.d/*.conf;是默认行为,所以站点配置单独放conf.d/下,不需要动主配置就能加站点。

# conf.d/default.conf 示例 server { listen 80; server_name localhost; location / { root /usr/share/nginx/html; index index.html; } location /nginx_status { stub_status on; access_log off; } }

离线环境下有两个配置习惯建议养成:一是 upstream 后端地址能用 IP 就别用域名,内网往往没有 DNS,域名解析失败会表现成启动正常但请求全 502,非常迷惑;二是 Tengine 的动态模块是.so文件,离线环境下很难补齐匹配版本的模块包,能用编译进主进程的静态功能就别依赖动态模块,省得给自己挖坑。

4. 启动后做三层验证:容器架构、请求响应与配置回显

部署脚本跑完只代表容器起来了,不代表服务可用。我的习惯是分三层验证:先看容器本身对不对,再打真实请求看响应,最后看配置和日志有没有隐性问题。

4.1 进程与架构验证:docker ps、docker exec 与 inspect 对照

# 容器是否在运行, 重启次数是否异常增长 docker ps --filter name=tengine-310 docker inspect tengine-310 --format '状态:{{.State.Status}} 重启次数:{{.RestartCount}}' # 进容器确认内部架构和主进程 docker exec tengine-310 uname -m docker exec tengine-310 cat /proc/1/cmdline | tr '\0' ' '

这里对照验证的意义是防止“容器跑起来了但里面是个错误产物”的情况。docker exec uname -m看的是容器内运行环境,/proc/1/cmdline显示主进程的完整启动参数,正常应该能看到nginx: master process字样。RestartCount如果持续增长,说明进程不断崩溃被 restart 策略拉起,这时候往下查日志比继续等更有意义。

4.2 请求与响应验证:curl -I 看 Server 头

# 本地打一次真实请求, 看响应头 curl -I http://127.0.0.1/ # 期望关键行: Server: Tengine/3.1.0 # 如果改了宿主机端口, 用对应端口测 curl -I http://127.0.0.1:8080/ # 确认监听状态 ss -lntp | grep -E ':80|:443'

curl -I只取响应头不拉正文,验证成本最低。Server 头是判断版本最直接的证据,Tengine 3.1.0 默认会回显Server: Tengine/3.1.0,如果看到的是nginx/1.x,说明镜像配置里把版本号隐藏或者实际上起的是另一个镜像,需要回去查 compose 的 image 字段和 load 的 tag 是否一致。ss -lntp是为了确认端口真的在监听,而不是 curl 走了别的代理。

4.3 配置校验与日志:nginx -t、docker logs 与持久化观察

# 配置语法校验, 离线改配置后必做 docker exec tengine-310 nginx -t # 看最近日志, 确认没有异常 warn docker logs tengine-310 --tail 50 # 确认日志真的写进了挂载目录 tail -5 ./logs/access.log 2>/dev/null || echo "日志目录还没有请求写入"

nginx -t是 Tengine 自带配置测试命令,会在不重启的情况下校验全部配置语法,报错会精确到文件和行号,改配置之后先跑它,比直接 restart 然后看挂没挂效率高得多。挂载的 access.log 如果始终没内容,优先怀疑挂载路径对不对,而不是服务没收到请求。黑匣子式排查不可取,日志是离线交付时唯一的现场证据。

5. 避坑:ARM64 离线部署 Tengine 的五个翻车点与排查方法

这一章全是交付现场真实踩过的坑,按现象、原因、解决三步写,照着对照就能省半天排查时间。

5.1 现象:load 成功却报 pull access denied

  • 原因:docker load会把镜像以原始的仓库名:tag导入,如果 compose 里写的image字段和原始 tag 不一致,compose 会尝试去远程仓库拉取,离线环境下自然 pull access denied。
  • 解决:docker images看实际导入的 REPOSITORY 和 TAG,然后docker tag 原仓库名:tag tengine:3.1.0改成 compose 期望的值,或者直接把 compose 的 image 字段改成 load 进来的原始 tag。推荐让 compose 和交付包约定一个固定 tag,比每次现场改 tag 靠谱。

5.2 现象:容器启动即退出,日志里有 exec format error

  • 原因:镜像架构不是 arm64,常见于在中转机上用 x86 拉取导出,或者在多架构仓库里 pull 到了 amd64 分支。ARM64 主机没有 QEMU 模拟层时,执行 x86 二进制直接报exec format error。
  • 解决:按第 2.2 节在 save 前用docker image inspect --format '{{.Architecture}}'确认是 arm64;如果交付包已经错了,回到中转机重新 pull arm64 分支再导出。不要试图在目标机上装 QEMU 硬跑,性能损失大,容器内的健康检查和探活都可能因时序问题误判。

5.3 现象:容器起来了,但宿主机端口不通

  • 原因:三类情况,宿主机 80 被其他服务占用、防火墙没放行、compose 端口映射没生效。
  • 解决:先ss -lntp | grep :80看谁在听,占用就改 compose 的"8080:80";确认映射生效用docker port tengine-310,它会回显宿主机端口到容器端口的对应关系;防火墙按目标机系统用firewall-cmd --list-ports或ufw status排查。端口映射是玄学重灾区,但绝大多数是这三件事,按顺序查五分钟内定位。

5.4 现象:页面 403 Forbidden

  • 原因:挂载的html目录权限不够。nginx 的 worker 进程以 nginx 用户运行,宿主目录如果是 700 权限或属主不匹配,worker 读不到静态文件,返回 403。
  • 解决:chmod 755 html并确认目录可读;麒麟等带 SELinux 的系统还要检查文件的安全上下文,临时验证用setenforce 0确认是不是 SELinux 拦截,确认后要么调整策略要么用chcon打标签。403 和 404 的差别值得记住:404 是文件不存在,403 是存在但没权限,前者查路径,后者查权限。

5.5 现象:docker-compose command not found 或 compose 命令报 unknown command

  • 原因:装错了形态。v1 是独立二进制,装在/usr/local/bin/docker-compose;v2 是 docker 插件,要放在 docker 的 cli-plugins 目录或者用 deb 包安装。现场常见的翻车是只装了 plugin 包,脚本里却调docker-compose,或者反过来。
  • 解决:交付脚本按第 3.2 节兼容两种形态;安装时明确目标机 docker 版本,20.10 以上用 v2 插件,老版本用 v1 二进制。离线现场最省心的做法是交付包同时带 aarch64 独立二进制,脚本优先用本地二进制,不依赖目标机预装。

6. 把部署包收敛成离线交付工具:目录规范、校验与升级路径

离线部署做到能跑只是第一步,做到能重复交付才是工具。我会把整个方案收敛成一个固定目录结构,每次交付只打包这一个目录。

tengine-offline-pack/ ├── tengine-3.1.0-arm64.tar # 离线镜像 ├── tengine-3.1.0-arm64.tar.sha256 # 镜像校验文件 ├── docker-compose # aarch64 独立二进制(可选) ├── deploy.sh # 一键部署脚本 ├── docker-compose.yml # 编排文件 ├── conf/ │ ├── nginx.conf │ └── conf.d/ └── html/ # 静态站点目录

到现场的执行顺序固定为三条:sha256sum -c验镜像完整性,./deploy.sh一键拉起,按第 4 章三层验证。校验这一步不能省,内网传输介质不可控,镜像 tar 损坏时docker load会报错,但报错信息可能误导到架构问题上,先校验再动手能直接排除一个变量。

升级路径上,我习惯保留旧镜像 tar 不删,新版本用独立 tag 导入,比如tengine:3.1.0和tengine:3.1.1并存,升级时只改 compose 的 image 字段再docker compose up -d --force-recreate。这样回滚也简单,改回旧 tag 再 up 一次就行,不用重新 load 镜像,这是离线环境里成本最低的后悔药。最后一条个人习惯:每次交付后在现场留一份 deploy 输出的文本日志,文件名带日期,下次出问题先翻它,能省掉一半远程沟通成本。希望帮到你。

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

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

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

立即咨询