Files
iotlcm/docs/deploy/offline.md
T
MiFaZhan b4944d7c21 docs: 部署手册镜像地址改为单仓库格式 iotlcm/iotlcm:<服务名>-<版本>
官方仓库把全部镜像放在同一个镜像仓库 iotlcm/iotlcm 下,靠 tag 区分服务:

  .../iotlcm/iotlcm:mysql-8.0
  .../iotlcm/iotlcm:iotlcm-admin-svr-v1.0.4
  .../iotlcm/iotlcm:iotlcm-app-server-v1.0.2

改动页面:
- prerequisites:镜像仓库章节重写,补充命名空间/镜像仓库/tag 三层结构说明,
  不再提 library/ 命名空间
- configuration:镜像地址示例与 tag 规则表
- build-image:构建命令、命名规则表、基础组件同步脚本、验证命令同步改
- offline:离线镜像清单
- split:分离部署示例

已构建通过,6 个相关页面均可访问。
2026-10-30 09:15:42 +08:00

4.4 KiB
Raw Blame History

title, description, outline
title description outline
离线部署 服务器无法访问镜像仓库时的部署方式 deep

离线部署

服务器无法访问外部镜像仓库时使用。核心思路:在有网机器上导出镜像 → 传到目标机 → 导入。

适用场景

  • 生产服务器在内网,不能访问外网
  • 镜像仓库在内网不可达,或需要走审批才能拉取
  • 需要把某一批镜像固化下来,保证多台机器部署一致

一、确定镜像清单

docker compose config --images | sort -u

输出示例(含可选 profile 时用 --profile 指定):

registry.example.com/iotlcm/iotlcm:iotlcm-admin-svr-v1.0.4
registry.example.com/iotlcm/iotlcm:iotlcm-admin-ui-v1.0.4
registry.example.com/iotlcm/iotlcm:iotlcm-app-server-v1.0.2
...
registry.example.com/iotlcm/iotlcm:mysql-8.0
registry.example.com/iotlcm/iotlcm:redis-7.2

把清单保存下来,作为这次部署的镜像基线:

docker compose config --images | sort -u > images.txt

二、在有网机器导出

# 拉取全部镜像
docker compose pull

# 导出为单个压缩包
docker save $(cat images.txt) | gzip > iotlcm-images-$(date +%Y%m%d).tar.gz

单包体积参考:全部 14 个服务约 1.5~2 GB(压缩后)。

若目标机磁盘紧张,可按服务分包:

for img in $(cat images.txt); do
  name=$(echo "$img" | tr '/:' '__')
  docker save "$img" | gzip > "img-${name}.tar.gz"
done

三、传输

scp iotlcm-images-*.tar.gz user@target-host:/opt/iotlcm/

无网络直连时用移动介质拷入,注意校验完整性:

# 源端生成校验值
sha256sum iotlcm-images-*.tar.gz > images.sha256

# 目标端校验
sha256sum -c images.sha256

四、在目标机导入

gunzip -c iotlcm-images-*.tar.gz | docker load

分包的逐个导入:

for f in img-*.tar.gz; do gunzip -c "$f" | docker load; done

验证:

docker images | grep iotlcm

五、部署

导入后镜像已在本机,compose 不会再尝试拉取:

# 把 docker-compose.yml 里的镜像地址与 TAG 改成与导入的镜像一致
cp -r config.example config
vi config/*/config.yaml

docker compose up -d

::: warning REGISTRY 与 TAG 必须与导入的镜像名一致 docker load 只恢复镜像名,不会改标签。若 docker-compose.yml 里写 TAG=latest 而导入的是 1.0.3,compose 会认为镜像不存在并尝试拉取,离线环境直接失败。

用这条命令核对:

docker compose config --images | sort -u > expected.txt
docker images --format '{{.Repository}}:{{.Tag}}' | sort -u > actual.txt
comm -23 expected.txt actual.txt    # 输出为空才说明镜像齐全

:::

六、长期方案:内网镜像仓库

如果需要经常部署或多机部署,建议搭内网镜像仓库,而不是每次传 tar 包。

同步镜像

# 在能访问外网的机器
for img in $(cat images.txt); do
  docker pull "$img"
  newimg="${img/registry.example.com/harbor.internal.example.com}"
  docker tag "$img" "$newimg"
  docker push "$newimg"
done

然后目标机的 docker-compose.yml 改为:

REGISTRY=harbor.internal.example.com

差异更新

版本升级时只需推送变化的镜像:

docker compose pull
# 对比 images.txt 找出新增/变更的标签,只同步这些

七、常见问题

现象 原因 处理
docker compose up 卡在 Pulling 镜像标签不匹配,compose 尝试联网拉取 按上文核对 expected.txt 与 actual.txt
no space left on device 镜像包 + 解压后镜像双份占盘 导入后删除 tar 包,或换挂载点
load 后 docker images 为空 压缩包损坏 用 sha256sum -c 校验
容器启动报 exec format error 架构不匹配(x86 镜像跑在 ARM) 在目标架构上重新导出
导出包过大 包含多个无用层 用 docker save 只导出必要标签

八、离线环境的其他准备

镜像只是第一步,以下也需提前准备:

资源 说明
部署仓代码 git clone 或直接打包 iotlcm-deploy/ 目录带过去
配置模板 已包含在部署仓 config/
数据库脚本 已包含在部署仓 schema/
Docker 与 Compose 目标机需预先安装,离线安装包需单独准备
时区数据 若使用 Asia/Shanghai,确认容器内 tzdata 完整(官方镜像已内置)