{"id":13446692,"url":"https://github.com/exdx/dcp","last_synced_at":"2025-04-13T05:34:11.189Z","repository":{"id":44150597,"uuid":"511979068","full_name":"exdx/dcp","owner":"exdx","description":"docker cp made easy","archived":false,"fork":false,"pushed_at":"2023-07-24T01:09:54.000Z","size":4095,"stargazers_count":110,"open_issues_count":15,"forks_count":3,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-03-26T22:51:13.895Z","etag":null,"topics":["containers","docker","docker-image","kubernetes"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/exdx.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-07-08T17:41:57.000Z","updated_at":"2024-12-20T08:42:54.000Z","dependencies_parsed_at":"2024-06-21T13:03:05.519Z","dependency_job_id":"b22b2223-7b12-4ebe-966e-9847153faadf","html_url":"https://github.com/exdx/dcp","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/exdx%2Fdcp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/exdx%2Fdcp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/exdx%2Fdcp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/exdx%2Fdcp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/exdx","download_url":"https://codeload.github.com/exdx/dcp/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248670520,"owners_count":21142896,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["containers","docker","docker-image","kubernetes"],"created_at":"2024-07-31T05:00:57.098Z","updated_at":"2025-04-13T05:34:09.370Z","avatar_url":"https://github.com/exdx.png","language":"Rust","readme":"# dcp: docker cp made easy\n\n[![GitHub Actions](https://github.com/exdx/dcp/workflows/ci/badge.svg)](https://github.com/exdx/dcp/actions)\n[![Latest version](https://img.shields.io/crates/v/dcp.svg)](https://crates.io/crates/dcp)\n[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)\n\n## Summary\n\nContainers are great tools that can encapsulate an application and its dependencies,\nallowing apps to run anywhere in a streamlined way. Some container images contain\ncommands to start a long-lived binary, whereas others may simply contain data\nthat needs to be available in the environment (for example, a Kubernetes cluster).\nFor example, [operator-framework bundles](https://olm.operatorframework.io/docs/tasks/creating-operator-bundle/) and [crossplane packages](https://crossplane.io/docs/v1.9/concepts/packages.html) both use\ncontainer images to store Kubernetes manifests. These manifests are unpacked and applied to the cluster.\n\nOne of the downsides of using container images to store data is that they are\nopaque. There's no way to quickly tell what's inside the image, although\nthe hash digest is useful in seeing whether the image has changed from a previous\nversion. The options are to use `docker cp` or something similar using podman\nor containerd.\n\nUsing `docker cp` by itself can be cumbersome. Say you have a remote image\nsomewhere in a registry. You have to pull the image, create a container from that\nimage, and only then run `docker cp \u003ccontainer-id\u003e` using an unintuitive syntax for selecting\nwhat should be copied to the local filesystem.\n\ndcp is a simple binary that simplifies this workflow. A user can simply\nsay `dcp \u003cimage-name\u003e` and dcp can extract the contents of that image onto the\nlocal filesystem. From there, users are free to view and edit the files locally. Any OCI-based image is supported. \n\n![Demo](demo.gif)\n\n## Installing\n\n### Installing from crates.io\n\nIf you're a Rust programmer and have Rust installed locally, you can install dcp\nby simply entering `cargo install dcp`, which will fetch the latest version from\ncrates.io.\ndcp relies on the stable Rust toolchain. \n\n### Download compiled binary\n\nThe [release section](https://github.com/exdx/dcp/releases) has a number\nof precompiled versions of dcp for different platforms. Linux, macOS, and Windows (experimental)\nbinaries are pre-built. For MacOS, both arm and x86 targets are provided, and\nfor Linux only x86 is provided. If your system is not supported, building dcp from\nthe source is straightforward.\n\n### Build from source\n\nTo build from source, ensure that you have the rust toolchain installed locally.\nThis project does not rely on nightly and uses the 1.62-stable toolchain.\nClone the repository and run `cargo build --release` to build a release version\nof the binary. From there, you can move the binary to a folder on your $PATH to access\nit easily.\n\n## Implementation\n\nBecause there wasn't a suitable `containerd` client implementation in Rust at the time\nof writing, dcp relies on APIs provided by external docker and podman crates. This limits dcp to working on systems where docker or podman is the container runtime.\n\nBy default, dcp will look for an active docker socket to connect to at the standard path. If the docker socket is unavailable, dcp will fallback to the current user's podman socket based on the $XDG_RUNTIME_DIR environment variable.\n\nIf the docker socket is on a remote host, or in a custom location, use the `-s` flag with the path to the custom socket.\n\n## Flags and Examples\n\nBy default, dcp will copy content to the current working directory. For example, lets try issuing the following command:\n\n```\n$ dcp tyslaton/sample-catalog:v0.0.4 -c configs\n```\n\nThis command will copy the `configs` directory (specified via the `-c` flag) from the image to the current directory.\n\nFor further configuration, lets try:\n\n```\n$ dcp tyslaton/sample-catalog:v0.0.4 -d output -c configs\n```\n\nThis command pulls down the requested image, only extracting\nthe `configs` directory and copying it to the `output` directory\nlocally (specified via the `-d` flag). If `output` does not exist locally,\nit will be created as part of the process. \n\nAnother example, for copying only the manifests directory:\n\n```\n$ dcp quay.io/tflannag/bundles:resolveset-v0.0.2 -c manifests\n```\n\nLastly, we can copy from a private image by providing a username\nand password (specified via the `-u` and `-p` flags).\n\n```\n$ dcp quay.io/tyslaton/sample-catalog-private:latest -u \u003cusername\u003e -p \u003cpassword\u003e\n```\n\n\u003e :warning: This serves as a convenient way to copy contents from a private image\nbut is insecure as your registry credentials are saved in\nyour shell history. If you would like to be completely secure then\nlogin via `\u003ccontainer_runtime\u003e login` and pull the image first. dcp \nwill then be able to find the image locally and process it.\n\n## FAQ\n\n**Q**: I hit an unexpected error unpacking the root filesystem of an image: `trying to unpack outside of destination path`. How can I avoid this?\n\n**A**: dcp relies on the underlying `tar` Rust library to unpack the image filesystem represented as a tar file. The [unpack](https://docs.rs/tar/latest/tar/struct.Archive.html#method.unpack) method is sensitive in that it will not write files outside of the path specified by the destination. So things like symlinks will cause errors when unpacking. Whenever possible, use the `-c` flag to specify a directory to unpack, instead of the container filesystem root, to avoid this error.\n\n------------------\n**Q**: I would like to use dcp to pull content from an image but I don't know where in the image the content is stored. Is there an `ls` command or similar functionality in dcp? \n\n**A**: Checkout the excellent [dive tool](https://github.com/wagoodman/dive) to easily explore a container filesystem by layer. After finding the path of the files to copy, you can then use dcp to extract just those specific files. \n\n------------------\n**Q**: Is dcp supported on Windows?\n\n**A**: Yes, dcp  is supported on Windows. Windows support is experimental, as there is no CI coverage, but it will likely work in your windows environment. The only non-default change you need to make is to expose the docker daemon so that dcp can connect to it. This can be done through one of two ways:\n\n1. Adding the following to your `%userprofile%\\.docker\\daemon.json` file.\n    ```json\n    {\n        \"hosts\": [\"tcp://0.0.0.0:2375\"]\n    }\n    ```\n\n2. Going through the Docker Desktop UI and enabling the setting for `Expose daemon on tcp://localhost:2375 without TLS` under `General`.\n\n\n------------------\n**Q**: I would like to inspect image labels to figure out where in the filesystem I should copy from. Does dcp have an `inspect` command to list image labels?\n\n**A**: Listing an image's labels can be done easily using the underlying container runtime. For example, run `docker image inspect \u003cimage-id\u003e | grep Labels` to see labels attached to an image. From there, dcp can be used to copy files from the container filesystem. \n\n## Testing\n\nIf you would like to run the test suite, you just need to run the standard cargo command. This will run all relevant\nunit, integration and documentation tests.\n\n```\n$ cargo test\n```\n","funding_links":[],"categories":["Container Operations","Rust"],"sub_categories":["User Interface"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexdx%2Fdcp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fexdx%2Fdcp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexdx%2Fdcp/lists"}