Skip to content

Feature Request: Support stdin/stdout streaming (-) in nerdctl cp #4691

@tinovyatkin

Description

@tinovyatkin

Summary

The nerdctl cp command does not support using - (dash) as source or destination path for streaming tar archives via stdin/stdout. This feature is available in Docker CLI and is essential for efficient file transfer operations in development tooling.

Docker Documentation

From Docker cp reference:

Using - as Source Path (stdin)

Using - as the SRC_PATH streams the contents of STDIN as a tar archive. The command extracts the content of the tar to the DEST_PATH in container's filesystem.

# Stream a tar archive into a container
cat archive.tar | docker cp - container:/path/

Using - as Destination Path (stdout)

Using - as the DEST_PATH streams the contents of the resource as a tar archive to STDOUT.

# Stream container contents to stdout
docker cp container:/var/log/app.log - | tar x -O | grep "ERROR"

Podman Compatibility

Podman fully supports stdin/stdout streaming:

  • Using - as src_path streams STDIN as a tar archive
  • Using - as dest_path streams the resource to STDOUT

Example from Podman docs:

podman cp - containerID:/myfiles.tar.gz < myfiles.tar.gz

Reference: Podman cp documentation

Use Cases

  1. IDE/Editor Extensions: VS Code Docker extension uses stdin streaming to efficiently write file contents directly to containers without creating temporary files on the host system.

  2. Backup/Restore Operations: Streaming allows piping container data directly to compression tools or remote storage without intermediate files.

  3. CI/CD Pipelines: Build systems often need to inject configuration or extract artifacts using piped operations for efficiency.

  4. Memory-Constrained Environments: Streaming avoids the need to buffer entire file contents in temporary files, which is important for large files.

Current Workaround

For VS Code Docker extension users, a workaround has been implemented in PR #327 that:

  • Uses shell commands with tar and mktemp for reading files
  • Creates temporary files for writing operations
  • Documents the platform assumptions (requires /bin/sh, tar, mktemp)
// Current workaround for readFile
const command = `/bin/sh -c '${escapedCommandName} cp ${escapedContainer}:${escapedPath} - | tar -xOf -'`;

// Current workaround for writeFile (uses temp file)
const command = `/bin/sh -c 'TMPFILE=$(mktemp) && cat > "$TMPFILE" && ${escapedCommandName} cp "$TMPFILE" ${escapedContainer}:${escapedPath} && rm -f "$TMPFILE"'`;

Current Behavior

# This doesn't work as expected
echo "content" | nerdctl cp - container:/path/file

# This also doesn't work
nerdctl cp container:/path/file -

Expected Behavior

# Stream content into container
echo "file content" | tar cf - --files-from=/dev/stdin | nerdctl cp - mycontainer:/app/

# Stream content from container
nerdctl cp mycontainer:/app/config.json - | tar xf - -O

Additional Context

This feature gap was identified while implementing Finch support for the VS Code Docker extension. Stdin/stdout streaming is fundamental to many Docker workflows and tooling integrations. Full Docker CLI compatibility for cp streaming would significantly improve the developer experience for users choosing Finch/nerdctl as their container runtime.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions