首页
/ Docker Compose export 命令详解:将服务容器文件系统导出为 tar 归档

Docker Compose export 命令详解:将服务容器文件系统导出为 tar 归档

2026-09-05 15:08:38作者:翟萌耘Ralph

docker compose export 用于把 Compose 项目中某个服务容器的文件系统打包导出为 tar 归档,其能力等价于对单个容器执行引擎 API 的 ContainerExport,但在 Compose 视角下以"服务名 + 副本索引"定位目标容器。本文基于 compose 仓库的命令参考文档与源码实现,完整解析该命令的参数、导出行为约束(终端输出限制、原子写入、dry-run)以及容器定位与调用链细节,帮助你在数据抢救、环境备份等场景中正确使用它,并理解底层实现。

一、命令概览:导出服务容器的文件系统

命令参考文档 compose_export.md 对该命令的定义是:

Export a service container's filesystem as a tar archive(将服务容器的文件系统导出为 tar 归档)

用法格式为:

docker compose export [OPTIONS] SERVICE

其中 SERVICE 为必填位置参数(命令定义Args: cobra.MinimumNArgs(1) 强制要求至少一个参数),且支持通过 ValidArgsFunction 对服务名做 Shell 自动补全。

选项一览

完整继承参考文档的选项表如下:

Name Type Default Description
--dry-run bool Execute command in dry run mode
--index int 0 index of the container if service has multiple replicas.
-o, --output string Write to a file, instead of STDOUT

几个值得注意的点:

  • --dry-run全局继承选项,并非 export 专属。在机器可读的命令定义 docker_compose_export.yaml 中,indexoutput 列在 options 段,而 dry-run 位于 inherited_options 段(默认值 false)。
  • --index 默认值为 0,仅在服务的容器有多个副本时才有意义。
  • -o--output 的短选项,用于把归档写入文件而非 STDOUT。

二、导出行为的关键约束

阅读 实现代码 pkg/compose/export.go 可以发现若干条文档未明说、但对实操影响很大的约束。

1. 输出到终端必须显式指定 -o

if options.Output == "" {
    if s.stdout().IsTerminal() {
        return fmt.Errorf("output option is required when exporting to terminal")
    }
} else if err := command.ValidateOutputPath(options.Output); err != nil {
    return fmt.Errorf("failed to export container: %w", err)
}

当 stdout 是交互式终端且未指定 -o 时,命令直接报错退出——避免二进制 tar 流打乱终端显示。也就是说:

  • docker compose export -o backup.tar app:写入文件;
  • docker compose export app > backup.tar:重定向到管道/文件是允许的(stdout 此时不是终端);
  • docker compose export app(在终端中直接运行):报错。

2. 文件写入采用原子写且权限为 0600

当指定了 -o 时,归档通过 atomicwriter 写入:

writer, err := atomicwriter.New(options.Output, 0o600)

这带来两个行为:目标文件以 0600 权限创建(仅属主可读写);写入以原子方式完成,中途失败不会留下半截文件。

3. --dry-run 只走流程、不落盘

if !s.dryRun {
    if options.Output == "" {
        _, err := io.Copy(s.stdout(), responseBody)
        ...
    } else {
        ...
        _, err = io.Copy(writer, responseBody)
        ...
    }
}

在 dry-run 模式下,引擎侧的 ContainerExport 调用仍然会发生(响应体被创建并关闭),但 io.Copy 写入步骤被整体跳过,即不产生归档文件。整个过程的事件状态(exporting → exported)仍会正常上报。

4. 执行过程的事件上报

导出开始与完成分别通过 s.events.On(...) 上报 StatusExportingWorking)与 StatusExportedDone)两类事件,资源 ID 为规范化容器名。这使 compose 的进度展示与 --dry-run 状态汇总能够覆盖 export 操作。

三、容器定位:服务名、--index 与 one-off 容器

export 不像 docker 原生命令那样直接接收容器 ID,而是通过 getSpecifiedContainer 按 Compose 语义定位目标容器:

container, err := s.getSpecifiedContainer(ctx, projectName, oneOffInclude, false, options.Service, options.Index)

该函数(pkg/compose/containers.go)的行为决定了几条重要规则:

  1. 只定位运行中的容器。调用参数 all=false,即 ContainerList 不带 All 过滤,已停止的容器不会被选中——若服务没有运行中容器,报错 service "xxx" is not running
  2. 支持 one-off 容器。传入的 oneOff 参数为 oneOffInclude,意味着 docker compose run 创建的 one-off 容器同样可以被 export(execattachcommit 等命令也复用同一 oneOffInclude 语义);
  3. --index 通过容器编号标签过滤。当 --index > 0 时,追加 label=com.docker.compose.container-number=<index> 过滤条件;若指定副本不存在,报错 service "xxx" is not running container #N
  4. 默认取编号最小的容器。结果按 com.docker.compose.container-number 标签升序排列,one-off 容器被排到末尾,最终取列表首项。

另外项目名在入口处会先做 strings.ToLower 归一化(pkg/compose/export.go),与 Compose 项目名统一小写的约定一致。

四、完整调用链:从 Cobra 命令到 Docker Engine API

整条链路如下,每一环都能在仓库中找到对应文件:

cmd/compose/export.go        cobra 命令解析,构建 api.ExportOptions
        │
        ▼
pkg/api/api.go               Compose 接口定义:Export(ctx, projectName, ExportOptions)
        │
        ▼
pkg/compose/export.go        composeService.Export → export()
        │   ① getSpecifiedContainer 定位运行中的目标容器
        │   ② 校验输出目标(终端 / -o 路径)
        │   ③ apiClient().ContainerExport 发起引擎 API
        │   ④ io.Copy 写 stdout 或 atomicwriter 落盘
        ▼
Docker Engine                POST /containers/{id}/export
  • 命令入口 cmd/compose/export.go:解析 SERVICE 位置参数与 --index-o 两个标志,组装 api.ExportOptions 后调用 backend.Export(ctx, projectName, exportOptions)
  • API 层选项结构(pkg/api/api.go):
// ExportOptions group options of the Export API
type ExportOptions struct {
    Service string
    Index   int
    Output  string
}
  • 服务层入口带统一的执行包装 Run(...) 与事件总线(pkg/compose/export.go),操作名上报为 "export"
  • 真正干活的是引擎客户端 ContainerExport,其 mock 与 dry-run 客户端分别在 mocks/mock_docker_api.gopkg/dryrun/dryrunclient.go 中有对应实现,后者保证 --dry-run 无需真实引擎也能走通全流程。

五、典型用法示例

以一个多副本服务为例:

# 导出 app 服务首个副本(编号最小)的容器文件系统
docker compose export -o app-fs.tar app

# 导出 app 服务的第 2 个副本
docker compose export --index 2 -o app-fs-2.tar app

# 直接通过管道处理(stdout 非终端,允许不指定 -o)
docker compose export app | tar -tvf - | head

# dry-run:走完整流程但不写入文件
docker compose export --dry-run -o /tmp/x.tar app

几点适用前提与限制:

  • 目标服务必须正在运行(停止的容器无法被选中);
  • 导出结果是容器当前文件系统快照(含运行期写入、未提交到镜像的变化),等价于 docker export 的语义,不包含镜像元数据;如需生成可复用镜像,应使用语义相近但方向不同的 docker compose commit(二者共用同一套容器定位逻辑,见 pkg/compose/commit.go);
  • 指定 -o 生成的文件权限为 0600,属主之外不可读,注意后续分发时的权限处理。

六、测试与机器可读定义

综合来看,docker compose export 把"按 Compose 语义找到容器"与"引擎级文件系统打包"组合成了一条命令:它以服务名为入口、以 --index 精确到副本、以 -o 安全落盘,是容器运行态数据抢救与备份时值得记住的工具。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
528
588
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
906
1.83 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
891
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.53 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.34 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
987
506
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384