# How to Export and Import Container Filesystems in the Apple Container Engine

> Easily export and import container filesystems using Apple Container Engine. Learn how to package and restore container root file systems as tar archives with simple CLI commands.

- Repository: [Apple/container](https://github.com/apple/container)
- Tags: how-to-guide
- Published: 2026-07-11

---

**The Apple Container Engine provides `container export` and `container import` CLI commands that package a container's root filesystem as a tar archive and restore it elsewhere, acting as thin wrappers around XPC-based Container API routes.**

The `apple/container` repository implements a complete container management system that includes functionality to snapshot and transport container filesystems. Understanding how to export and import container filesystems enables you to backup stopped containers, migrate workloads between hosts, and archive container states. This guide examines the source code implementation and provides practical usage examples for both operations.

## Understanding the Export and Import Workflow

Both commands follow a consistent four-step pattern that involves temporary file management, XPC communication with the daemon, and automatic cleanup.

### Exporting a Container Filesystem

When you run `container export`, the system creates a temporary directory, requests the daemon to stream the container's root filesystem into a tar archive, then either pipes the result to stdout or moves it to your specified output path. The temporary directory is removed in a `defer` block to ensure no stray files remain.

### Importing a Container Filesystem

The `container import` command reverses this process by creating a temporary location for the incoming tar payload, sending an `XPCMessage` with route `containerImport` to the daemon, and building a new container image from the archive contents. Once complete, the cleanup logic removes the temporary files.

## CLI Commands and Usage Examples

The following commands demonstrate how to move container filesystems in and out of the Apple Container Engine.

### Export a Stopped Container

Export the filesystem of a stopped container (ID `abc123`) to stdout:

```bash
container export abc123 > abc123.tar

```

Export directly to a file using the `-o` flag:

```bash
container export abc123 -o abc123.tar

```

### Import a Tar Archive

Create a new container from an exported tar file:

```bash
container import abc123.tar

```

Import from stdin using the `-` argument, useful for piping operations:

```bash
cat abc123.tar | container import -

```

## Implementation Details in the Source Code

The export and import functionality spans multiple layers of the codebase, from CLI parsing to daemon-side route handling.

### Export Command Implementation

In [`Sources/ContainerCommands/Container/ContainerExport.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Container/ContainerExport.swift), the export command defines CLI options, initializes a temporary directory at `FileManager.default.temporaryDirectory`, and constructs the archive path as `archive.tar`. The command invokes `client.export(id:archive:)` to trigger the XPC communication, then streams bytes to stdout or moves the temporary file to the output location.

### Client-Side API Communication

The [`Sources/Services/ContainerAPIService/Client/ContainerClient.swift`](https://github.com/apple/container/blob/main/Sources/Services/ContainerAPIService/Client/ContainerClient.swift) file contains the `export(id:archive:)` method that constructs an `XPCMessage` with the route `containerExport`. This message transmits the container ID and temporary archive location to the daemon process.

### Daemon Route Registration

The daemon receives these requests through routes registered in `Sources/APIServer/APIServer+Start.swift`. This file maps `XPCRoute.containerExport` and `XPCRoute.containerImport` to their respective handler functions, enabling the daemon to stream filesystem data into tar archives during export or reconstruct containers from tar payloads during import.

## Important Limitations and Requirements

**The export command requires the target container to be stopped.** Attempting to export a running container results in an error from the daemon. Both commands utilize temporary directories that are automatically cleaned up after the operation completes, regardless of success or failure.

## Summary

- **Export and import container filesystems** using `container export` and `container import`, which wrap XPC-based Container API routes.
- The implementation resides in [`Sources/ContainerCommands/Container/ContainerExport.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Container/ContainerExport.swift) and related daemon files in the `apple/container` repository.
- Export requires stopped containers and outputs to stdout by default or to a file via the `-o` flag.
- Import accepts file paths or stdin (`-`) and creates a new container from the tar archive.
- Temporary files are managed automatically and cleaned up via `defer` blocks in both command implementations.

## Frequently Asked Questions

### Can I export a running container?

No. According to the `apple/container` source code, the export command requires the target container to be stopped. Attempting to export a running container will result in an error returned from the daemon.

### What format does the export use?

The export command creates a standard **tar archive** containing the container's root filesystem. The daemon streams the filesystem contents into this format, making it compatible with standard Unix tar tools and the `container import` command.

### How do I import from stdin?

Use the `-` argument with `container import` to read from stdin. This is useful in pipelines, such as `cat archive.tar | container import -`, allowing you to stream archives directly without intermediate files.

### Where are temporary files stored during export?

The command creates temporary directories using `FileManager.default.temporaryDirectory` and writes the archive to `archive.tar` inside that location. These files are automatically removed in a `defer` block after the operation completes, ensuring no residual data remains on the host.