Docker 镜像拉取与离线分发实践 Docker 镜像拉取与离线分发实践背景在内网部署、离线交付、跨环境迁移时常见需求不是直接运行容器而是先把镜像拉到本地再导出成文件发给其他人。这类场景下最稳妥的流程通常是docker pull将目标镜像拉到本地docker save将镜像导出为.tar按统一命名规则整理文件将导出的包分发给目标环境对方使用docker load导入本文整理一套可直接复用的操作方式。核心命令拉取镜像dockerpull 镜像名:tag导出镜像dockersave-omyimage.tar 镜像名:tag例如dockerpull nginx:latestdockersave-onginx--latest.tar nginx:latest为什么用docker savedocker save导出的是镜像本身适合做离线分发。它和下面几种方式的区别需要分清docker save导出镜像适合发送给别人导入。docker export导出容器文件系统不保留镜像层和元数据通常不适合镜像分发。直接拷贝 Docker Desktop 的底层磁盘文件不适合单镜像交付文件大且不可控。如果目标是“把某个镜像发给别人用”优先选docker save。命名规则为了便于识别和批量管理可以将导出文件命名为镜像名最后一个 path--tag.tar例如docker.io/library/nginx:latest导出后命名为nginx--latest.tar再例如docker.io/library/mysql:8.0导出后命名为mysql--8.0.tar这个规则的优点很直接文件名短适合分发能保留服务名和版本号比把完整仓库路径塞进文件名更清晰单个镜像导出下面是一套最小操作imagenginx:latestrepo${image%:*}tag${image##*:}name${repo##*/}dockerpull$imagedockersave-o${name}--${tag}.tar$image执行后会生成nginx--latest.tar批量导出镜像如果镜像很多手工执行容易出错。更实用的做法是写一个简单脚本。#!/usr/bin/env bashset-uout_dir./web-imagesmkdir-p$out_dirimages(nginx:latestmysql:8.0redis:7.2)forimagein${images[]};dorepo${image%:*}tag${image##*:}name${repo##*/}tar_path${out_dir}/${name}--${tag}.tarecho$imagedockerpull$image||continuedockersave-o$tar_path$image||continueechoSAVED -$tar_pathdone这个脚本的特点是逻辑简单便于维护目录按用途分开比如web-images、db-images文件名统一某个镜像失败不会阻塞后续镜像实际整理方式如果项目里存在多套业务镜像建议按目录区分web-images/ nginx--latest.tar redis--7.2.tar db-images/ mysql--8.0.tar postgres--16.tar这样比全部堆在一个目录里更好管理尤其适合按系统交付按环境备份按项目归档常见问题1.docker save生成的是不是“压缩包”严格来说docker save生成的是.tar包不一定是压缩过的。如果你还想进一步压缩可以再执行gzipnginx--latest.tar压缩后会变成nginx--latest.tar.gz但很多场景下直接保留.tar就已经够用了。2. 为什么docker pull会提示unauthorized这通常不是命令写错而是仓库权限问题。常见原因有没有执行docker login当前账号没有目标仓库拉取权限镜像路径写错tag 不存在遇到这种情况先确认dockerlogin然后再重试docker pull。3.docker save会不会带上容器运行时的数据不会。docker save只导出镜像不包含容器运行过程中写入的数据卷内容。如果你需要一起迁移业务数据还要额外处理Docker volume挂载目录数据库备份4. 对方如何使用导出的镜像对方收到.tar后直接执行dockerload-inginx--latest.tar导入完成后可通过下面命令确认dockerimages推荐的交付流程比较稳妥的一套流程如下整理镜像清单创建分类目录例如web-images、db-images批量执行docker pull按服务名--版本.tar导出校验导出文件是否齐全如有需要再统一压缩或打总包交付对方使用docker load导入一套可直接复用的模板#!/usr/bin/env bashset-uout_dir./imagesmkdir-p$out_dirimages(镜像1:tag镜像2:tag镜像3:tag)forimagein${images[]};dorepo${image%:*}tag${image##*:}name${repo##*/}tar_path${out_dir}/${name}--${tag}.tarechopull -$imagedockerpull$image||{echopull failed:$imagecontinue}echosave -$tar_pathdockersave-o$tar_path$image||{echosave failed:$imagecontinue}done总结如果目标是做离线交付最实用的办法就是docker pull - docker save - 统一命名 - 分类归档 - docker load这里最关键的不是命令本身而是两点命名规则要统一目录结构要清晰当镜像数量一多规范化管理比单次执行更重要。