docker-pull-tar: pulling a multi-architecture image as a tar file on a machine with no Docker
无需 Docker 环境,就能直接搜索、下载多架构(如 arm、x86)的 Docker 镜像并保存为 tar 包。Search and download multi-architecture (e.g., arm, x86) Docker images directly as tar files without needing a Docker environment.
At a glance
- What is it?
- This Python tool downloads Docker images straight from a registry, picks the architecture, resumes after a broken connection and writes a.tar file you can carry into an air-gapped network. There is also a Gradio web version that wraps the same flow in a browser, and the version it reports does not match the newest tagged release.
- Who is it for?
- This tool is worth adopting for the narrow and real job of moving an image into a network that has no registry access, since it produces a plain .tar file that any Docker host can load, and it does not need a daemon on the machine that fetches it.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 51 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The core use is a .tar file that a Docker host can load later
The project calls itself Docker Image Puller, and its stated purpose is to pull images from a Docker registry with resume support and multi-architecture selection. The README states that the tool uses the MIT license and is open source so that users can customise and extend it as needed.
The design decision that defines the tool is that it never needs a Docker environment. The feature list opens with the claim that neither Docker nor Python has to be installed, since you can use a single file EXE or a Python script straight away, and the second point repeats it for the EXE, compiled as a standalone file that runs with no dependencies at all.
What you get at the end is a directory named after the image, its tag and its architecture, containing a .tar file, and the README gives the import command that the file is designed for:
docker load -i library_alpine_latest_amd64.tarThe path the file takes is the classic air-gapped transfer, and the README spells it out in four steps. Pull and package the image with this tool, move the .tar across by USB stick, internal file server or similar, load it on the target machine with `docker load`, then confirm it with `docker images` and start a container with `docker run -it alpine`.
That workflow is the reason the tool exists, and it explains the otherwise odd feature set. Resumable downloads matter when the source is slow and the file is large. Retries matter because a flaky link otherwise means starting a multi-gigabyte fetch again. The mirror and proxy options exist because in some networks the direct route to a registry is the slowest one available.
Four scripts and two build paths, which is more than the README implies
The repository root tells a clearer story than the README does about how this project grew.
The entries are app.py, build.bat, build_lite.bat, clear.bat, docker_image_puller.py, docker_image_puller_1ms.py, dev.md, favicon.ico, requirements.txt, version.txt, screenshots/ and the usual LICENSE and README. So there are three Python scripts, two build scripts for Windows, a clear script, a development notes file and a separate version file.
The two pullers are not variants of the same thing. docker_image_puller_1ms.py is the edition tailored to the 1ms.run image registry, and the README describes it as offering keyword search and one-click download, so that you can type a keyword instead of knowing the full image name, see a result table with download counts and stars, then pick a tag and an architecture. It has its own flag set for that workflow, with `--keyword` and `--image` as mutually exclusive choices, `--tag`, `--arch`, `--output`, `--workers`, and an `--api` defaulting to https://1ms.run/api/v1/registry plus a `--registry` defaulting to docker.1ms.run.
The generic tool, docker_image_puller.py, is the one the main usage section documents, and its flags are different: `--image`, `--arch`, `--custom-registry`, `--username`, `--password`, `--output`, `--quiet`, `--debug`, `--workers`, `--version` and `--help`.
The two build scripts make the same point about packaging. build.bat and build_lite.bat produce two different executables, and the EXE that the download section offers is called DockerPull.exe. Which script produces which binary is not stated in the README, and the repository also carries a version.txt that the interactive banner reads, which is where the discrepancy in the next section comes from.
The version numbers do not agree with the release list
The README and the published releases describe different versions of this tool, and anyone writing a deployment script around it needs to know which is which.
The recent releases are v1.2.0 from 2025-12-04, v1.0.7 from 2025-02-05 and v1.0.6 from 2025-01-24. The interactive session banner in the usage example reads a pull tool name and v1.4.0. The last push was on 2026-09-02, so the repository has moved since v1.2.0 was tagged, and the version shown in the example is higher than the newest published release rather than lower.
Read together, that suggests the tagged releases and the version in the working tree are numbered separately, or that the release process has not been run for the current state of the code. The repository carries a version.txt, which is consistent with the version being read from a file rather than from a package manifest, and the requirements.txt pins exact versions of the dependencies with no project version of its own, since this is a script rather than an installed package.
There is also a gap in the release history itself. Between v1.0.7 in February 2025 and v1.2.0 in December 2025 there is a long quiet stretch, and the release titles in the list are in Chinese and read as a feature increase for v1.2.0 and a change that makes the architecture optional for the user to pick for v1.0.7. Since the last push was on 2026-09-02, the project is not archived, but a tool with no release since December 2025 is worth pinning by commit if you depend on it.
Resumable downloads, bounded retries and a checksum on every layer
The reliability section is the most specific part of the README, and it is where the tool earns its place next to a plain `docker pull`.
Resume works by writing a progress file into the output directory, and running the same command again after a network interruption or a crash continues from the breakpoint rather than starting over. The README ties the resume guarantee to the same command being re-run, which is the behaviour you would want on a link that drops periodically.
Retries are bounded and different per failure class, which is a reasonable design. An authentication failure is retried at most three times, a failure to fetch the manifest is retried at most three times, and a file download failure is retried at most ten times. The strategy is exponential backoff, so a failing registry is not hammered.
Integrity is checked per layer with SHA256, and the README says a failed verification deletes the damaged file and downloads it again. That is the detail that matters for the tar use case, because a silently corrupt layer inside a .tar file produces a broken image that only fails much later, on the machine that finally loads it.
Signal handling is also there: Ctrl+C exits gracefully, and the download progress is saved on exit. In other words, the tool is written on the assumption that the download will be interrupted, which is the honest assumption when the source is a public registry over an unreliable link.
The Gradio front end is a different product with a different dependency footprint
There is now a web version, and the README presents it as a separate application rather than a skin over the command line tool.
It is app.py, a Gradio interface that makes the whole flow visual. The README describes a one-stop web console, a keyword search that returns a table with image name, star count, pull count and update date, a linked selection where clicking a row on the left loads the tag list on the right, dropdowns for tag and architecture, a proxy panel with radio buttons for no proxy, system proxy or a custom proxy with credentials, and a toggle for SSL verification. There is a live progress panel with per-chunk status, a total percentage, per-layer download amounts and an estimated real-time speed, and a local management panel listing downloaded .tar files with the option to download them to the current device or delete them.
Running it takes two commands:
pip install -r requirements.txtpython app.pyThe README says that once the terminal prints its startup message, you open http://127.0.0.1:7860 in a browser. The port is fixed in the documentation, which matters if you plan to run it on a shared machine.
The dependency picture changes with this front end. requirements.txt pins certifi, charset-normalizer, idna, requests, tqdm and urllib3 at exact versions, and then adds `gradio>=6.14.0` with no upper bound. A Gradio release that changes behaviour will therefore change what this tool does, and the only version constraint in the whole file is a floor rather than a pin. The web version also pulls in a local file management panel that can serve .tar files to a browser, which is convenient and is also the piece to think about before putting the app on a shared host.
The 1ms edition offers a search path the generic tool does not
The search feature is worth separating, because it is not available in the documented command line workflow of the generic tool.
The 1ms edition is built around the 1ms.run registry and starts with a keyword. The README lists keyword search, so you do not need to know the full image name, a smart recommendation that shows the download count and stars for each result to help pick a popular image, automatic tag list retrieval, automatic architecture detection with a choice, concurrent downloads to speed up large pulls, and no Docker environment required since the result is a .tar file for internal transfer.
The documented parameter table is short enough to reproduce. `-k, --keyword` is the search keyword, `-i, --image` is the image name and the two are mutually exclusive, `-t, --tag` is the tag and is selected from the list if not passed, `-a, --arch` defaults to amd64, `-o, --output` is the output directory, `-w, --workers` is the number of concurrent download threads and defaults to 4, `--api` is the 1ms API address with a default of https://1ms.run/api/v1/registry, and `--registry` is the 1ms registry address with a default of docker.1ms.run.
The examples show the three levels of use:
python docker_image_puller_1ms.py
python docker_image_puller_1ms.py -k nginx
python docker_image_puller_1ms.py -i nginx -t latest -a arm64One thing to be careful about is where the search results come from. The web version lists 1ms, a domestic mirror and the official Docker source as switchable data sources, and the search table shows star counts and pull counts that are properties of a search index rather than of the registry itself. Those numbers are a hint for choosing an image, not a statement about quality, and the README does not say which index serves them.
Where this tool is the wrong choice
There are two situations where a different tool is the better answer, and one where this tool has a real weakness.
For a build pipeline, this is the wrong tool. Every documented entry point is human-facing: the interactive prompt asks for the image name, the registry, the username and the password, and the tag and architecture are chosen from a list. There is no documented flag combination that produces a tar file from a variable with no output to the terminal, and there is no exit-code contract described for a CI step. The generic tool does have `-q, --quiet` for reduced interaction and `--debug` for verbose logs, which is closer to scriptable, but the README does not promise silence on stdout.
Where a mirror or a pull-through cache exists, this is the wrong tool. The README's own answer to the question about configuring a domestic mirror is to use the `-r` parameter or set `HTTP_PROXY` and `HTTPS_PROXY`, and the web version ships mirror sources as one-click options. Pointing a daemon at a mirror registry is simpler and gives you a real `docker pull` with the same result.
The real weakness is the credential handling. The flag list has `-u, --username` and `-p, --password` as command line options, and the example passes them literally, as in `DockerPull.exe -i harbor.example.com/library/nginx:1.26.0 -u admin -p password`. A password on the command line is visible to anyone listing processes on the machine and lands in shell history, and the README does not mention reading credentials from a file, from an environment variable, or from a Docker config. For a private registry with real credentials, that is a problem the tool does not appear to address, and it is the first thing to check before running it on a shared host.
Editorial conclusion
This tool is worth adopting for the narrow and real job of moving an image into a network that has no registry access, since it produces a plain .tar file that any Docker host can load, and it does not need a daemon on the machine that fetches it. It is the wrong tool for a build pipeline, because it is a human-facing downloader with an interactive prompt and no documented scriptable output, and it is the wrong tool where a mirror or a pull-through cache is available, since the README itself points at mirror sources as the faster route. Before adopting, check which of the two front ends you actually need, because the command line tool and the Gradio app are separate scripts with separate flags, and confirm the version you download matches the README, since the interactive banner reads v1.4.0 while the newest published release is v1.2.0.
Frequently asked questions
Do I need Docker installed to use docker-pull-tar?
No. The README states the tool can be run as a single file EXE or a Python script with neither Docker nor a Python environment required, and it produces a .tar file that is loaded later with docker load.
How do I download a specific architecture of a Docker image?
Use the -a or --arch flag, which defaults to amd64, alongside the image name. The interactive mode lists the available architectures and prompts for a choice, and the README examples include pulling alpine for arm64 and a multi-architecture image from quay.io.
What happens if the download is interrupted?
Running the same command again continues from the breakpoint, because the progress file is kept in the output directory. The README also says Ctrl+C exits gracefully and saves the download progress on exit.
How do I import the downloaded image on a machine inside an internal network?
Copy the .tar file to the target machine and run docker load -i library_alpine_latest_amd64.tar, then confirm with docker images and start a container with docker run -it alpine.
Does docker-pull-tar have a web interface?
Yes, app.py is a Gradio application with a search table, tag and architecture dropdowns, a live progress panel and a local tar file management panel. It is installed with pip install -r requirements.txt and started with python app.py, then opened at http://127.0.0.1:7860.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/topcss-docker-pull-tar)Was this useful?