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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions