服务器无法直接拉取镜像时如何离线传输镜像?

本文适用于:

  • • Docker 20+ / 24+
  • • 服务器处于内网环境,无法访问外网
  • • 防火墙策略限制,无法拉取外部镜像
  • • 需要批量部署相同镜像到多台服务器

⚠️ 重要提示

当服务器无法直接拉取镜像时,通过 docker save/load 实现离线传输是最可靠的方案。

操作流程:

有网络机器:docker pull → docker save → 传输 tar 文件
  ↓
目标服务器:接收 tar 文件 → docker load → 完成

✅ 推荐做法

使用 docker save 保存镜像为 tar 文件,通过 SCP/FTP 传输。在目标服务器使用 docker load 加载,无需网络连接即可使用。

如果您的服务器因为网络限制、防火墙策略或无法访问外网等原因,无法直接使用 docker pull 命令拉取镜像,可以通过离线传输的方式将镜像文件传输到服务器上。

适用场景

  • 服务器处于内网环境,无法访问外网
  • 防火墙策略限制,无法拉取外部镜像
  • 网络不稳定,直接拉取经常失败
  • 需要批量部署相同镜像到多台服务器

操作步骤

步骤 1:在有网络的机器上拉取镜像

找一台可以正常访问外网、没有防火墙限制的机器(可以是您的个人电脑、跳板机或其他服务器),执行以下命令拉取镜像:

docker pull <镜像名:tag>

示例:

# 拉取 nginx 镜像 docker pull nginx:latest # 拉取自定义镜像(带域名前缀) docker pull xxx.xuanyuan.run/library/nginx:latest

步骤 2:将镜像保存为离线包(tar 文件)

使用 docker save 命令将镜像保存为 tar 格式的离线包:

docker save <镜像名:tag> -o image.tar

示例:

# 保存 nginx 镜像 docker save nginx:latest -o nginx-latest.tar # 也可以指定完整路径 docker save nginx:latest -o /tmp/nginx-latest.tar

💡 提示:

  • 保存后的 tar 文件大小通常与镜像大小相近,请确保有足够的磁盘空间
  • 可以使用 ls -lh image.tar 查看文件大小
  • 如果需要保存多个镜像,可以一次性保存:docker save image1:tag image2:tag -o images.tar
  • 磁盘空间不足时:如果服务器磁盘空间不够保存完整的 tar 文件,可以直接使用流式传输方式(见步骤 3 的方式 4),无需先保存文件

步骤 3:传输 tar 文件到目标服务器

将生成的 tar 文件传输到您的目标服务器。可以使用以下任意方式:

方式 1:使用 SCP 命令(推荐)

scp image.tar user@服务器IP:/目标路径/
# 示例:传输到服务器的 /tmp 目录 scp nginx-latest.tar root@192.168.1.100:/tmp/

方式 2:使用 FTP/SFTP 工具

使用 FileZilla、WinSCP 等 FTP/SFTP 客户端工具,通过图形界面将文件上传到服务器。

方式 3:使用 U 盘或其他物理介质

如果服务器完全隔离,可以通过 U 盘、移动硬盘等物理介质拷贝文件。

方式 4:流式传输(适用于磁盘空间不足的情况)

如果源服务器或目标服务器磁盘空间不足,无法先保存完整的 tar 文件,可以使用流式传输方式,直接将镜像通过管道传输到目标服务器,无需在本地保存中间文件。

📊 数据流:

docker save(标准输出)
  ↓
gzip 压缩
  ↓
SSH 加密传输
  ↓
远端 cat 写文件

✅ 优点:

  • 本地不落盘:无需在源服务器上保存 tar 文件,不占磁盘空间
  • 一边导出一边传:镜像导出和传输同时进行,提高效率
  • 非常适合磁盘小、镜像大的迁移场景

基础命令:

docker save <镜像名:tag> | gzip | ssh -p <端口> <用户名>@<ip地址> 'cat > /path/镜像.tar.gz'

🚀 推荐:带进度条版本(强烈建议)

没有进度条的迁移,等得人会怀疑人生 😅。可以使用 pv(生产环境神器)显示传输进度:

docker save <镜像名:tag> | pv | gzip -1 | ssh -p <端口> <用户名>@<ip地址> 'cat > /path/镜像.tar.gz'
# 示例:流式传输 nginx 镜像(带进度条) docker save nginx:latest | pv | gzip -1 | ssh -p 22 root@192.168.1.100 'cat > /tmp/nginx-latest.tar.gz' # 如果使用非标准 SSH 端口 docker save nginx:latest | pv | gzip -1 | ssh -p 2222 root@192.168.1.100 'cat > /tmp/nginx-latest.tar.gz' # 如果系统没有安装 pv,可以使用以下命令安装: # Ubuntu/Debian: apt-get install pv # CentOS/RHEL: yum install pv # macOS: brew install pv

💡 说明:

  • 使用 pv 可以实时显示传输速度、进度和预计剩余时间
  • gzip -1 使用最低压缩级别,加快压缩速度,适合实时传输场景
  • 目标服务器上会直接生成压缩后的 tar.gz 文件
  • 加载时需要使用:gunzip -c /path/镜像.tar.gz | docker load

🚀 进阶玩法:不落盘直接导入(高阶)

如果目标服务器磁盘也紧张,可以做到完全不落盘,直接导入到 Docker:

docker save <镜像名:tag> | gzip -1 | ssh -p <端口> <用户名>@<ip地址> 'gunzip | docker load'

📊 数据流:

docker save(标准输出)
  ↓
gzip 压缩
  ↓
SSH 加密传输
  ↓
远端 gunzip 解压
  ↓
远端 docker load 直接导入

✅ 效果:

  • 本地:不落盘 - 源服务器不保存任何文件
  • 远端:不落盘 - 目标服务器也不保存任何文件
  • 全程流式,导出即导入 - 镜像从导出到导入一气呵成
# 示例:不落盘直接导入 nginx 镜像 docker save nginx:latest | gzip -1 | ssh -p 22 root@192.168.1.100 'gunzip | docker load' # 带进度条版本(推荐) docker save nginx:latest | pv | gzip -1 | ssh -p 22 root@192.168.1.100 'gunzip | docker load' # 如果使用非标准 SSH 端口 docker save nginx:latest | pv | gzip -1 | ssh -p 2222 root@192.168.1.100 'gunzip | docker load'

💡 适用场景:当源服务器和目标服务器磁盘空间都非常紧张时,这是最节省空间的方案。镜像传输完成后直接导入到 Docker,无需任何中间文件。

步骤 4:在目标服务器上加载镜像

在目标服务器上,使用 docker load 命令加载离线镜像包:

docker load -i image.tar

示例:

# 加载镜像 docker load -i /tmp/nginx-latest.tar # 加载完成后,可以使用 docker images 查看 docker images | grep nginx

💡 如果使用的是压缩文件(.tar.gz):

如果传输的是压缩后的 tar.gz 文件(如使用流式传输方式),需要使用以下命令加载:

gunzip -c image.tar.gz | docker load
# 示例:加载压缩的镜像文件 gunzip -c /tmp/nginx-latest.tar.gz | docker load

✅ 验证:加载成功后,使用 docker images 命令可以看到镜像已经加载到本地,之后就可以正常使用 docker run 等命令了。

完整操作示例

以下是一个完整的操作示例,演示如何将 nginx 镜像从有网络的机器传输到内网服务器:

# ===== 在有网络的机器上操作 ===== # 1. 拉取镜像 $ docker pull nginx:latest latest: Pulling from library/nginx ... # 2. 保存为离线包 $ docker save nginx:latest -o nginx-latest.tar $ ls -lh nginx-latest.tar -rw-r--r-- 1 user user 150M nginx-latest.tar # 3. 传输到目标服务器(假设服务器IP为 192.168.1.100) $ scp nginx-latest.tar root@192.168.1.100:/tmp/ nginx-latest.tar 100% 150MB 10.0MB/s 00:15 # ===== 在目标服务器上操作 ===== # 4. 登录到目标服务器 $ ssh root@192.168.1.100 # 5. 加载镜像 $ docker load -i /tmp/nginx-latest.tar Loaded image: nginx:latest # 6. 验证镜像已加载 $ docker images | grep nginx nginx latest abc123def456 2 minutes ago 150MB # 7. 现在可以正常使用镜像了 $ docker run -d -p 80:80 nginx:latest

注意事项

  • 镜像名称和标签:使用 docker save 保存的镜像,加载后会保持原有的镜像名称和标签。如果镜像名称包含域名前缀(如 xxx.xuanyuan.run/library/nginx:latest),加载后也会保持这个名称。
  • 磁盘空间:确保目标服务器有足够的磁盘空间来存储镜像文件。镜像 tar 文件的大小通常与镜像本身大小相近。
  • Docker 版本:确保目标服务器已安装 Docker,并且版本不要太旧,建议使用 Docker 20.10 或更高版本。
  • 批量传输:如果需要传输多个镜像,可以一次性保存多个镜像到一个 tar 文件:docker save image1:tag image2:tag image3:tag -o all-images.tar
  • 压缩传输:如果网络带宽有限,可以在保存时使用 gzip 压缩,但需要配合 docker load 使用管道:docker save image:tag | gzip > image.tar.gz,加载时:gunzip -c image.tar.gz | docker load
  • 磁盘空间不足:如果源服务器或目标服务器磁盘空间不足,无法保存完整的 tar 文件,可以使用流式传输方式:docker save image:tag | gzip | ssh -p 端口 用户名@ip地址 'cat > /path/镜像.tar.gz',这样无需在本地保存中间文件,直接通过管道传输到目标服务器。强烈建议使用 pv 显示进度:docker save image:tag | pv | gzip -1 | ssh -p 端口 用户名@ip地址 'cat > /path/镜像.tar.gz',可以实时查看传输速度、进度和预计剩余时间。
  • 完全不落盘(高阶):如果源服务器和目标服务器磁盘空间都非常紧张,可以使用完全不落盘的方案:docker save image:tag | gzip -1 | ssh -p 端口 用户名@ip地址 'gunzip | docker load',镜像从导出到导入全程流式处理,本地和远端都不保存任何文件,真正做到导出即导入。

总结:

  • ✅ 在有网络的机器上使用 docker pull 拉取镜像
  • ✅ 使用 docker save 将镜像保存为 tar 文件
  • ✅ 通过 SCP、FTP 或其他方式将 tar 文件传输到目标服务器
  • ✅ 在目标服务器上使用 docker load 加载镜像
  • ✅ 加载完成后即可正常使用镜像,无需网络连接

本文由「xuanyuan.cloud」维护
专注国内 Docker / 镜像 / Registry 网络问题
内容基于真实用户环境与实测

咨询镜像拉取问题请 提交工单,官方技术交流群:1072982923
轩辕镜像面向开发者与科研用户,提供开源镜像的搜索和访问支持。所有镜像均来源于原始仓库,本站不存储、不修改、不传播任何镜像内容。