MCPcopy Index your code
hub / github.com/bitnami/charts-syncer

github.com/bitnami/charts-syncer @v2.4.3

Chat with this repo
repository ↗ · DeepWiki ↗ · release v2.4.3 ↗ · + Follow
508 symbols 1,630 edges 57 files 296 documented · 58%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Go Report Card CI

charts-syncer

Sync Helm chart packages and OCI container images between repositories

[!IMPORTANT]
Starting in 2026, this project is licensed under a Broadcom license. For details, see the LICENSE file

Table of Contents

Usage

Sync all Helm Charts

$ charts-syncer sync

Sync Helm Charts from a specific date

$ charts-syncer sync --from-date 2020-05-15

Sync latest version of each Helm Chart

$ charts-syncer sync --latest-version-only

Syncing Container Images

In addition to Helm charts, charts-syncer can sync standalone OCI container images between registries. This is configured via the source.containers and target.containers sections in the config file, independently of the source.repo / target.repo sections used for chart syncing.

Container images are identified by a registry base URL and a list of image names. charts-syncer will discover all available tags for each image in the source registry, compare them against the target, and only transfer what is missing.

[!NOTE] The container tag discovery uses the naming pattern MAJOR.MINOR.PATCH-DISTRO_NAME-DISTRO_VERSION-rREVISION (e.g. 7.4.1-debian-12-r6). Tags that do not follow this pattern (such as latest or digest references) are excluded from auto-discovery.

Sync container images only

To sync container images without any Helm charts, define only the containers sections. The repo section is not required for OCI registries — charts-syncer will use the containers.url directly:

source:
  repo:
    kind: OCI
  containers:
    url: https://source-registry.example.com/myproject/containers
    auth:
      username: "SOURCE_USERNAME"
      password: "SOURCE_PASSWORD"

target:
  repo:
    kind: OCI
  containers:
    url: https://target-registry.example.com/myproject/containers
    auth:
      username: "TARGET_USERNAME"
      password: "TARGET_PASSWORD"

containers:
  - redis
  - nginx
  - postgresql
$ charts-syncer sync

If you want to sync containers to a local directory instead of a remote registry, set repo.kind: LOCAL and specify a path. In this case containers.url is not needed:

source:
  containers:
    url: https://source-registry.example.com/myproject/containers
    auth:
      username: "SOURCE_USERNAME"
      password: "SOURCE_PASSWORD"

target:
  repo:
    kind: LOCAL
    path: /tmp/my-local-containers

containers:
  - redis
  - nginx
$ charts-syncer sync

Sync Helm Charts and Container Images together

Both sections can coexist in the same config file. charts-syncer will run the chart sync and the container sync sequentially in the same invocation.

The repo.kind field is required when syncing charts (it determines which chart repository backend to use). The containers.url field drives where container images are read from and written to:

source:
  repo:
    kind: OCI
    url: https://source-registry.example.com/myproject/charts
    auth:
      username: "SOURCE_USERNAME"
      password: "SOURCE_PASSWORD"
  containers:
    url: https://source-registry.example.com/myproject/containers
    auth:
      username: "SOURCE_USERNAME"
      password: "SOURCE_PASSWORD"

target:
  repo:
    kind: OCI
    url: https://target-registry.example.com/myproject/charts
    auth:
      username: "TARGET_USERNAME"
      password: "TARGET_PASSWORD"
  containers:
    url: https://target-registry.example.com/myproject/containers
    auth:
      username: "TARGET_USERNAME"
      password: "TARGET_PASSWORD"

charts:
  - redis
  - mariadb

containers:
  - redis
  - mariadb
$ charts-syncer sync

Sync latest version of each container

Use --latest-version-only to sync only the highest available tag for each container name. This flag also applies to chart syncing when both sections are configured:

$ charts-syncer sync --latest-version-only

Advanced Usage

Sync only specific container platforms

By default, all container platforms are sync-ed to the destination registry, but this behavior can by tweaked by defining a list of platforms to sync:

#
# Example config file
#
source:
  repo:
    kind: OCI
    url: http://localhost:8080
target:
  # Container images registry authn
  repo:
    kind: OCI
    url: http://localhost:9090/charts

containerPlatforms:
  - linux/amd64

charts:
  - redis
  - mariadb

Skip syncing artifacts

If your chart and docker images include artifacts such as signatures or metadata, they will be synced to the destination repository. If you want to disable this behavior, you can opt out by setting skipArtifacts to true:

source:
  repo:
    kind: OCI
    url: http://localhost:8080
target:
  repo:
    kind: OCI
    url: http://localhost:9090/charts
charts:
  - redis

skipArtifacts: true

This is especially useful when you filter the container platforms to sync, which would invalidate the signatures. Using skipArtifacts: true will prevent syncing the now invalid signatures:

source:
  repo:
    kind: OCI
    url: http://localhost:8080
target:
  repo:
    kind: OCI
    url: http://localhost:9090/charts
charts:
  - redis
skipArtifacts: true
containerPlatforms:
  - linux/amd64

Skip syncing images

By default images referenced in charts will be synced and their refences in the chart will be updated to the target repo. If you want to disable this behavior, you can opt out by setting skipImages to true:

source:
  repo:
    kind: OCI
    url: http://localhost:8080
target:
  repo:
    kind: OCI
    url: http://localhost:9090/charts
charts:
  - redis

skipImages: true

Sync Helm Charts and Container Images to different registries

By default, charts-syncer syncs Helm Charts packages and their container images to the same registry specified in the target.repo.url property. If you require to configure a different destination registry for the images, this can be configured in the target.containers.url property:

#
# Example config file
#
source:
  repo:
    kind: OCI
    url: http://localhost:8080
target:
  # Container images registry authn
  containers:
    url: http://localhost:9090/containers
    auth:
      username: "USERNAME"
      password: "PASSWORD"
  repo:
    kind: OCI
    url: http://localhost:9090/charts
    # Helm repository authentication
    # auth:
    #   username: "USERNAME"
    #   password: "PASSWORD"
charts:
  - redis
  - mariadb

Sync Helm Charts and associated container images between disconnected environments

There are scenarios where the source and target Helm Charts repositories are not reachable at the same time from the same location.

For those cases, charts-syncer supports a two steps relocation for offline Chart and container images transport, check the air gap docs.


Configuration

Below you can find an example configuration file. To know all the available configuration keys see the charts-syncer file as it includes explanatory comments for each configuration key.

#
# Example config file
#
source:
  repo:
    kind: HELM
    url: http://localhost:8080
    # Helm repository authentication, same for other repo types i.e OCI
    # auth:
    #   username: "USERNAME"
    #   password: "PASSWORD"
  # Container images source registry (required for standalone container sync)
  # containers:
  #   url: http://localhost:8080/containers
  #   auth:
  #     username: "USERNAME"
  #     password: "PASSWORD"
target:
  repo:
    kind: OCI
    url: http://localhost:9090
    # Helm repository authentication
    # auth:
    #   username: "USERNAME"
    #   password: "PASSWORD"
  # Container images target registry (required for standalone container sync)
  # containers:
  #   url: http://localhost:9090/containers
  #   auth:
  #     username: "USERNAME"
  #     password: "PASSWORD"
charts:
  - redis
  - mariadb
# opt-out counterpart of "charts" property that explicitly lists the Helm charts to be skipped
# either "charts" or "skipCharts" can be used at once
# skipCharts:
#  - mariadb

# List of container image names to sync (used when containers sections are configured)
# containers:
#   - redis
#   - mariadb

[!TIP] Note that the repo.url property you need to specify is the same one you would use to add the repo to Helm with the helm repo add command. Example: helm repo add bitnami https://charts.bitnami.com/bitnami.

Credentials for the Helm Chart repositories and container images registries can be provided using a config file or the following environment variables:

Helm Chart repositories

  • SOURCE_REPO_AUTH_USERNAME
  • SOURCE_REPO_AUTH_PASSWORD

  • TARGET_REPO_AUTH_USERNAME

  • TARGET_REPO_AUTH_PASSWORD

Container images registries

  • SOURCE_CONTAINERS_AUTH_REGISTRY
  • SOURCE_CONTAINERS_AUTH_USERNAME
  • SOURCE_CONTAINERS_AUTH_PASSWORD

  • TARGET_CONTAINERS_AUTH_USERNAME

  • TARGET_CONTAINERS_AUTH_PASSWORD

Current available Kinds are LOCAL, HELM, CHARTMUSEUM, HARBOR and OCI for the Source Repo and OCI and LOCAL for the Target Repo.

[!NOTE] The list of charts in the config file is optional except for OCI repositories used as source. The rest of chart repositories kinds already support autodiscovery.

[!NOTE] The list of containers in the config file is always required when using standalone container syncing, as auto-discovery is not supported for container registries.

Google Artifact Registry example (Tanzu Application Catalog hosted registry)

The Google Artifact Registry (GAR) is the default option for Tanzu Application Catalog hosted registries.

Before running the charts syncer, it's recommended to test registry connectivity. You can do that by downloading the JSON file with credentials and try logging in with docker cli:

$ cat _json_key.json | docker login -u _json_key --password-stdin https://YOUR_REGISTRY

Tanzu Application Catalog credentials are in JSON multiline format. The simplest and recommended option for using chart-syncer configuration is to base64 encode this credentials on a single line

$ cat _json_key.json | base64
ewogICJ0eXBlIjogInNlcnZpY2VfYWNjb3VudCIsCiAgInByb2plY3Rfa......

The output from the previous command is a long single line of base64 encoded content. That will be the registry password. The registry username is the special name _json_key_base64 that hints Google that credentials are base64 encoded.

See below an example of configuration file using GAR and Debian 12 Helm charts and containers:

source:
  repo:
    kind: OCI
    url: https://us-east1-docker.pkg.dev/vmw-app-catalog/hosted-registry-YOUR_ID/charts/debian-12
    auth:
      username: _json_key_base64
      password: __YOUR_BASE64_ENCODED_PASSWORD_HERE__
  containers:
    auth:
      registry: https://us-east1-docker.pkg.dev/vmw-app-catalog/hosted-registry-YOUR_ID/containers/debian-12
      username: _json_key_base64
      password: __YOUR_BASE64_ENCODED_PASSWORD_HERE__

target:
  repo:
    kind: OCI
    url: https://YOUR_REGISTRY/tac-charts
    auth:
      username: ${TARGET_REPO_AUTH_USERNAME} # Username for target repo authentication
      password: ${TARGET_REPO_AUTH_PASSWORD} # Password for target repo authentication

Harbor example

In the case of HARBOR kind repos, be aware that chart repository URLs are:

https://$HARBOR_DOMAIN/chartrepo/$HARBOR_PROJECT

So if HARBOR_DOMAIN=my.harbor.com and HARBOR_PROJECT=my-project, you would need to specify this repo in the config file like:

source:
 repo:
   kind: HARBOR
   url: https://my.harbor.com/chartrepo/my-project

OCI example

Since Harbor 2.0.0, there

Extension points exported contracts — how you extend this code

ChartsReader (Interface)
This package defines the interfaces that clients needs to satisfy in order to work with chart repositories or intermedia [5 …
pkg/client/client.go
Storer (Interface)
Storer defines the methods that a Cache should implement to write. [1 implementers]
internal/cache/cache.go
Indexer (Interface)
Indexer is the interface that an indexer should implement [1 implementers]
internal/indexer/indexer.go
FakeSyncerOption (FuncType)
FakeSyncerOption is an option value used to create a new fake syncer instance.
pkg/chartsyncer/fakesyncer.go
Option (FuncType)
Option is an option value used to create a new syncer instance.
pkg/containersyncer/syncer.go
FetchOption (FuncType)
FetchOption defines a fetchOptions setting
internal/utils/utils.go
ChartsWriter (Interface)
ChartsWriter defines the methods that a WriteOnly chart or bundle client should implement. [5 implementers]
pkg/client/client.go
Fetcher (Interface)
Fetcher defines the methods that a Cache should implement to read. [1 implementers]
internal/cache/cache.go

Core symbols most depended-on inside this repo

Errorf
called by 123
internal/log/logger.go
Infof
called by 39
internal/log/logger.go
String
called by 15
pkg/client/types/types.go
Dir
called by 12
pkg/client/repo/local/local.go
Fetch
called by 10
pkg/client/client.go
List
called by 10
pkg/client/client.go
Has
called by 9
pkg/client/client.go
ListChartVersions
called by 8
pkg/client/client.go

Shape

Method 247
Function 189
Struct 46
Interface 15
FuncType 9
TypeAlias 2

Languages

Go100%

Modules by API surface

gen/proto/v1/config.pb.go79 symbols
internal/indexer/api/index.pb.go30 symbols
internal/utils/utils.go27 symbols
pkg/client/client.go23 symbols
pkg/client/repo/oci/oci.go21 symbols
pkg/client/repo/oci/ocitester.go19 symbols
pkg/chartsyncer/syncer.go16 symbols
pkg/client/repo/helmclassic/helmclassic.go14 symbols
pkg/client/repo/local/local.go13 symbols
pkg/containersyncer/syncer.go12 symbols
pkg/client/types/types.go12 symbols
pkg/client/repo/helmclassic/helmclassictester.go12 symbols

For agents

$ claude mcp add charts-syncer \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page