Skip to main content

Mirror container images via OCI tarballs

Project description

regmirror

Mirror container images through OCI tarballs to a private registry.

regmirror uses skopeo to pull images from any public or private registry, store them as OCI archive tarballs on disk, and re-push them to a private registry with automatic domain path rewriting.

Why?

Air-gapped or restricted environments often can't reach public registries directly. regmirror lets you:

  1. Pull images on a machine with internet access
  2. Transfer the tarballs to the restricted environment (USB, S3, SCP, etc.)
  3. Push them to an internal registry with predictable, collision-free names

Requirements

  • Python 3.10+
  • skopeo installed and on $PATH

Installation

uv tool install regmirror

Or run without installing:

uvx regmirror

Alternatively with pipx/pip:

pipx install regmirror
# or
pip install regmirror

Usage

Download images to tarballs

./regmirror.py download -f images.txt -o ./tarballs

Upload tarballs to a private registry

./regmirror.py upload -d ./tarballs -r my.registry.tld

Download and upload in one step

./regmirror.py sync -f images.txt -o ./tarballs -r my.registry.tld

Preview the manifest and upload targets

./regmirror.py list -d ./tarballs -r my.registry.tld

Image list file

The -f / --file argument points to a plain text file with one image reference per line. Lines starting with # are ignored.

# Example images.txt
nginx:1.25
docker.io/library/redis:7
gcr.io/google-containers/pause:3.9
quay.io/prometheus/prometheus:v2.51.0

Name rewriting

Source registry domains are flattened into a path prefix to avoid conflicts:

Source Target
docker.io/library/nginx:1.25 my.registry.tld/dockerio/library/nginx:1.25
gcr.io/project/app:v1 my.registry.tld/gcrio/project/app:v1
quay.io/prometheus/prometheus:v2.51.0 my.registry.tld/quayio/prometheus/prometheus:v2.51.0

manifest.json

Every download run writes a manifest.json into the tarball directory. This file maps each tarball filename back to its original image reference, making the conversion fully reversible without fragile filename encoding.

{
  "nginx-1.25.tar": {
    "original": "nginx:1.25",
    "registry": "docker.io",
    "image": "library/nginx",
    "tag": "1.25",
    "digest": "sha256:a484819eb60211f5299034ac80f6a681b06f89e476600f94c25bde91c7f7e88c"
  }
}

After a successful download the resolved sha256: digest is stored alongside the tag. On subsequent runs regmirror uses this digest to detect whether the tag now points to a newer image — if it does, the tarball is re-downloaded automatically. Use --force to re-download unconditionally regardless of the stored digest.

The upload and list commands require this file to be present.

Command reference

download

Flag Default Description
-f, --file (required) Text file with image references
-o, --output ./tarballs Directory to write tarballs and manifest
--force false Re-download tarballs unconditionally, ignoring stored digest
--src-tls-verify BOOL Override TLS verification for the source registry
--src-creds USER:PASS Credentials for the source registry
--authfile FILE Path to a Docker-compatible auth.json
--remove-signatures auto Strip embedded image signatures; applied automatically when detected, or pass explicitly to always strip

upload

Flag Default Description
-d, --dir ./tarballs Directory containing tarballs and manifest
-r, --registry (required) Target registry (e.g. my.registry.tld)
--dest-tls-verify BOOL Override TLS verification for the target registry
--dest-creds USER:PASS Credentials for the target registry
--authfile FILE Path to a Docker-compatible auth.json
--remove-signatures false Strip image signatures during push

sync

Accepts all flags from both download and upload, plus:

Flag Default Description
--continue-on-error false Continue with upload even if some downloads failed

list

Flag Default Description
-d, --dir ./tarballs Directory containing the manifest
-r, --registry Preview what the upload targets would be

Building the package

Install the build tools:

pip install build hatchling

Build both the wheel and source distribution:

python -m build

This outputs dist/regmirror-<version>-py3-none-any.whl and dist/regmirror-<version>.tar.gz.

Install locally to test before publishing:

uv tool install dist/regmirror-*.whl
# or
pipx install dist/regmirror-*.whl

Publish to PyPI:

pip install twine
twine upload dist/*

Global flags

Flag Description
--dry-run Print skopeo commands without executing them
--version Print version and exit

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

regmirror-1.2.1.tar.gz (21.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

regmirror-1.2.1-py3-none-any.whl (21.3 kB view details)

Uploaded Python 3

File details

Details for the file regmirror-1.2.1.tar.gz.

File metadata

  • Download URL: regmirror-1.2.1.tar.gz
  • Upload date:
  • Size: 21.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for regmirror-1.2.1.tar.gz
Algorithm Hash digest
SHA256 a122089e1bf24cf1972457ec15d0f8d5306254e7e9630482878484da2bfd1f5a
MD5 0af87be22fb71af233f65569a530d448
BLAKE2b-256 f78b029eba583ca79f078e6a700d2de5fdc08e46473aa744ce0bab468c4cac3d

See more details on using hashes here.

Provenance

The following attestation bundles were made for regmirror-1.2.1.tar.gz:

Publisher: publish.yml on WatskeBart/regmirror

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file regmirror-1.2.1-py3-none-any.whl.

File metadata

  • Download URL: regmirror-1.2.1-py3-none-any.whl
  • Upload date:
  • Size: 21.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for regmirror-1.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3dd04005b57cf9e8b01879bdb3019aa84efd5577be3372b0514d6bc2285daa2d
MD5 70bacb6d885b0c058dcd564271258df7
BLAKE2b-256 69f865ca7eaa0418c2d39766320edd8c18ffe5ece1c30a51daca29c481985591

See more details on using hashes here.

Provenance

The following attestation bundles were made for regmirror-1.2.1-py3-none-any.whl:

Publisher: publish.yml on WatskeBart/regmirror

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page