A CLI tool to mirror helm charts and docker images from public registries to local/private repositories.
Project description
xrepomirror
A CLI tool to mirror Docker images and Helm charts from public registries to local/private repositories. Designed for air-gapped or restricted environments where workloads cannot pull directly from the internet.
Features
- Mirror Docker images via
docker pull/docker tag/docker push - Mirror Helm charts via
helm pull/helm push(OCI) or Nexus 3 REST API upload - Proxy support via configurable environment variables
- Single
sources.yamlconfiguration file, or recursively process a directory tree of sources files - Optional per-image
destination:override to control the destination image name and tag - Supports Python 3.6 and above
Requirements
- Python 3.6+
dockerCLI — available and authenticated to the destination registryhelmCLI (v3) — available and authenticated to the destination registry (for Helm mirroring)
Installation
pip install xrepomirror
Or install from source:
git clone https://github.com/tkdpython/xrepomirror.git
cd xrepomirror
pip install .
Configuration
Create a sources.yaml file in your working directory. The file has two top-level keys: sources and settings.
Full example
sources:
docker_images:
- source: docker.io/grafana/grafana:12.3.0
- source: ghcr.io/grafana/grafana-operator:v5.21.3
destination: grafana-operator # keeps source tag, renames image
- source: quay.io/prometheus/prometheus:v3.9.1
destination: prometheus:v3.9.1-local # explicit name and tag
helm_charts:
- chart: kube-prometheus-stack
repo: https://prometheus-community.github.io/helm-charts
version: 80.13.3
- chart: grafana-operator
repo: https://grafana.github.io/helm-charts
version: 5.21.4
settings:
destination_repositories:
docker:
repo: ctr.example.com
helm:
repo: repo.example.com/helm
type: nexus3 # "nexus3" or "oci" (default: "oci")
env_vars:
HTTP_PROXY: http://proxy.local:8080
HTTPS_PROXY: http://proxy.local:8080
NO_PROXY: .mycompany.co.uk,.svc,.local,localhost
sources
| Key | Description |
|---|---|
docker_images |
List of Docker image references to mirror. Each entry requires a source key with the full image reference including tag. An optional destination key overrides the destination image name (see Docker image destination naming). |
helm_charts |
List of Helm charts to mirror. Each entry requires chart (chart name), repo (upstream Helm repo URL), and version. |
settings
| Key | Description |
|---|---|
destination_repositories.docker.repo |
Destination Docker registry host/prefix (e.g. ctr.example.com). |
destination_repositories.helm.repo |
Destination Helm repository. For OCI this is the registry path; for Nexus 3 this is <host>/<repo-name>. |
destination_repositories.helm.type |
How to upload Helm charts — "oci" (default, uses helm push) or "nexus3" (uses the Nexus 3 REST API). |
env_vars |
Key/value pairs to set as environment variables before any operations. Existing variables are not overwritten, so values can be overridden at runtime. |
Usage
xrepomirror [--sources FILE | --sources-tree DIR] [--skip-docker] [--skip-helm]
| Flag | Description |
|---|---|
--sources FILE |
Path to a single sources YAML file (default: sources.yaml in the current directory). Mutually exclusive with --sources-tree. |
--sources-tree DIR |
Recursively search DIR for sources.yaml / sources.yml files and process each valid one in turn. Mutually exclusive with --sources. |
--skip-docker |
Skip mirroring Docker images. |
--skip-helm |
Skip mirroring Helm charts. |
--version |
Print the version and exit. |
Examples
Mirror everything using the default sources.yaml:
xrepomirror
Mirror only Helm charts:
xrepomirror --skip-docker
Mirror only Docker images using a custom config file:
xrepomirror --sources /path/to/my-sources.yaml --skip-helm
Process all sources files found under a directory tree:
xrepomirror --sources-tree ./mirror-configs
Docker image destination naming
The destination image reference is determined by an optional destination key on each docker image entry:
| Entry | Destination (ctr.example.com) |
|---|---|
source: docker.io/grafana/grafana:12.3.0 (no destination) |
ctr.example.com/docker.io/grafana/grafana:12.3.0 |
source: docker.io/grafana/grafana:12.3.0destination: grafana (name only) |
ctr.example.com/grafana:12.3.0 (source tag preserved) |
source: docker.io/grafana/grafana:12.3.0destination: grafana:superversion (name + tag) |
ctr.example.com/grafana:superversion |
When no destination is given the full source reference (including the original registry) is appended to the destination repo, preserving the complete image path.
Helm destination types
OCI (default)
Charts are pushed using helm push to an OCI-compatible registry:
settings:
destination_repositories:
helm:
repo: ctr.example.com/helm-charts
type: oci
Nexus 3
Charts are uploaded via the Nexus 3 REST API (POST /service/rest/v1/components). The repo value must be in the format <host>/<repository-name>:
settings:
destination_repositories:
helm:
repo: repo.example.com/helm
type: nexus3
Proxy support
Set env_vars in sources.yaml to inject proxy settings before any network operations. Standard proxy variables are supported: HTTP_PROXY, HTTPS_PROXY, NO_PROXY (and their lowercase equivalents). Variables that are already set in the shell environment take precedence over values in sources.yaml.
Dependencies
| Package | Purpose |
|---|---|
PyYAML>=5.1 |
Parsing sources.yaml |
requests>=2.20.0 |
Nexus 3 REST API uploads |
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file xrepomirror-0.2.0.tar.gz.
File metadata
- Download URL: xrepomirror-0.2.0.tar.gz
- Upload date:
- Size: 12.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5eaaea13a326df10074471bde4331a16d94cc3a476a9e6bc7b50fd2d5a855718
|
|
| MD5 |
3c4ccb2d44a1a146576f3092448b292f
|
|
| BLAKE2b-256 |
65a4398a1d97cf33f4b0fe9c3a441255d2e7ae4c7f3202eeb0c1a4671ce8e57a
|
Provenance
The following attestation bundles were made for xrepomirror-0.2.0.tar.gz:
Publisher:
publish.yml on tkdpython/xrepomirror
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
xrepomirror-0.2.0.tar.gz -
Subject digest:
5eaaea13a326df10074471bde4331a16d94cc3a476a9e6bc7b50fd2d5a855718 - Sigstore transparency entry: 1342708600
- Sigstore integration time:
-
Permalink:
tkdpython/xrepomirror@820eae882e0ad59c699d4c3ac302907d7cb8d7d5 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/tkdpython
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@820eae882e0ad59c699d4c3ac302907d7cb8d7d5 -
Trigger Event:
push
-
Statement type:
File details
Details for the file xrepomirror-0.2.0-py3-none-any.whl.
File metadata
- Download URL: xrepomirror-0.2.0-py3-none-any.whl
- Upload date:
- Size: 13.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
35c08b5086a5a5d6e0f40113ab4fde6846a840ba1d604b28ae429c1c08dd2ff2
|
|
| MD5 |
70cea72d0b126589ce9e4b6d8465ec50
|
|
| BLAKE2b-256 |
a8899d7e7c18f29cb6587ae23e00d327a8d8d0721bdbd01ac32a87f861dce7d5
|
Provenance
The following attestation bundles were made for xrepomirror-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on tkdpython/xrepomirror
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
xrepomirror-0.2.0-py3-none-any.whl -
Subject digest:
35c08b5086a5a5d6e0f40113ab4fde6846a840ba1d604b28ae429c1c08dd2ff2 - Sigstore transparency entry: 1342708601
- Sigstore integration time:
-
Permalink:
tkdpython/xrepomirror@820eae882e0ad59c699d4c3ac302907d7cb8d7d5 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/tkdpython
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@820eae882e0ad59c699d4c3ac302907d7cb8d7d5 -
Trigger Event:
push
-
Statement type: