42d12d905a
mirror-to-gitee / mirror (push) Successful in 5s
版本号与功能一一对应:小程序线功能停在 v1.0.2,镜像 tag 也停在 v1.0.2, 平台后续发 v1.0.5 时它不动。 - deploy/docker-compose.yml:app-server / app-web 两行回退 v1.0.2 - Makefile:IMAGE_MAP 增加第 5 列「固定版本」,app 两行填 v1.0.2, 本地构建与 CI 行为一致 - 根 README:新增「小程序线是独立版本线」说明 - app/README.md:标注本目录对应 v1.0.2,不跟随平台 tag - 文档:deploy/README 版本表、build-image 的 tag 表与说明、 offline / prerequisites / configuration 示例 tag 全部回退 v1.0.2 CI 侧由 Jenkins 流水线的 PIN 表(app|v1.0.2)保证:tag 构建自动跳过 app, 需要重建时单独触发 SERVICES=app VERSION=v1.0.2。
4.4 KiB
4.4 KiB
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 或直接打包 deploy/ 目录带过去 |
| 配置模板 | 已包含在部署仓 config/ |
| 数据库脚本 | 已包含在部署仓 schema/ |
| Docker 与 Compose | 目标机需预先安装,离线安装包需单独准备 |
| 时区数据 | 若使用 Asia/Shanghai,确认容器内 tzdata 完整(官方镜像已内置) |