Zum Inhalt springen
iits
Unsere Arbeit
ENDE
Kontakt→
Kontakt→
iits
Unsere Arbeit
Kontakt→
Sprache
ENDE
Dortmund Office · Westfalendamm 279 · 44141 Dortmund

LEISTUNGEN

Alle LeistungenKI & Machine LearningSoftwareentwicklungCloud & DevOpsIoTProduktstrategie & ManagementUX & UI DesignTalent SolutionsBranchen

WORKSHOPS

KI-Discovery WorkshopSoftware-Architektur-WorkshopCloud Architecture WorkshopKostenloser UX-AuditBuild-vs-Buy-Bewertung
© 2026 iits-consulting.
  • Impressum
  • Datenschutz
  • AGB
  1. Blog
  2. /DevOps & CloudOps

Argo CD: How to Use a private OCI Helm Chart Repository

Learn how to complete an Argo CD Private OCI Helm Repository Setup with Docker, GitLab, and Harbor. Secure Helm charts and automate deployments.

Von Alexander Hoeft · 13. März 2025 · 12 Min. Lesezeit

Teilen
Argo CD: How to Use a private OCI Helm Chart Repository

Auf dieser Seite

  • Difference Between a Private Helm Repository and a Private OCI Helm Repository
  • Docker OCI: Setting Up a Private OCI Helm Repository with Argo CD
  • GitLab OCI: Setting Up a Private OCI Helm Repository with Argo CD
  • Step 1: Create a GitLab Access Token
  • Harbor OCI: Setting Up a Private OCI Helm Repository with Argo CD
  • Step 4: Add the Private Harbor OCI Helm Repository to Argo CD
  • 4.1 Add via Argo CD UI
  • Final Thoughts
  • Thank You!

Research-Power auf Deadline?

Let's talk→

Step-by-Step Guide to Setting Up a Private OCI Helm Repository with Argo CD, GitOps, Docker, GitLab, and Harbor


Note: When you start looking into this topic, you’ll come across countless GitHub issues with various solutions. Some work, some don’t. At first, we were confused by the many conflicting recommendations, so we decided to create a clean and reliable setup for different private Helm repositories. We = Alexander Hoeft, Philip Siemer, Daniel Schlosser and Artem Lajko
Fig.0: Deploying Cert-Manager from a Mirrored Private OCI Registry (Harbor)
Fig.0: Deploying Cert-Manager from a Mirrored Private OCI Registry (Harbor)

There are various scenarios where you might need more than just hosting your own Helm charts in a private registry. For example, you may need to mirror and sign Helm charts before making them available in a private repository. This private registry is often used by different customers to deploy signed Helm charts on their respective clusters. In many cases, these clusters don’t have internet access, or policies (e.g., Kyverno) restrict pulling images only from specific Helm chart repositories.

Starting April 1, 2025, Docker will introduce new pull rate limits:

  • Unauthenticated users: 10 pulls per hour
  • Authenticated users (free account): 100 pulls per hour
  • Pro, Team, and Business subscribers: Unlimited pulls (with fair use)

Container image mirroring and Helm chart signing are essential best practices. With Docker’s new pull rate limits, private repositories are now more critical than ever.

Alright, enough theory — let’s dive into the hands-on part and see how to set up private OCI Helm repositories across different platforms!

Difference Between a Private Helm Repository and a Private OCI Helm Repository

When working with Argo CD, there are key differences between a Helm private repository and a Helm OCI private repository. The distinction isn’t just about the protocol — it also affects how Argo CD integrates these repositories and how secrets need to be configured.

For this guide, we’ll focus exclusively on OCI-based repositories, as we consider OCI the industry standard. OCI support has been available since Helm 3.8.0, making it the preferred approach moving forward.

This how you configure it in the Argo CD GUI. Go to Settings -> Repositories and hit + CONNECT RREPO.

Fig. 1: Argo CD GUI: + CONNECT REPO
Fig. 1: Argo CD GUI: + CONNECT REPO
Fig. 2: Argo CD GUI: + CONNECT REPO (Enable OCI)
Fig. 2: Argo CD GUI: + CONNECT REPO (Enable OCI)

Don’t forget to enable OCI!

When using an OCI-enabled Helm repository, the secret in Argo CD looks like this:

YAML
apiVersion: v1
data:
  enableOCI: dHJ1ZQ==
  name: ZG9ja2VyLW9jaQ==
  password: Z.....
  project: ZGVmYXVsdA==
  type: aGVsbQ==
  url: cmVnaXN0cnktMS5kb2NrZXIuaW8= (registry-1.docker.io)
  username: YXJ0ZW1sYQ==
kind: Secret
metadata:
  annotations:
    managed-by: argocd.argoproj.io
  labels:
    argocd.argoproj.io/secret-type: repository
  name: repo-2984550025
  namespace: argocd
type: Opaque


What’s Different About OCI in Argo CD?

  1. No Protocol Prefix (oci://) Needed:
  • Unlike traditional Helm repositories (htttps), you don’t manually specify the oci:// protocol in Argo CD.
  • Argo CD automatically applies this when working with OCI-based registries.

2. URL Structure (No Repository Path):

  • The URL field only contains the registry address (e.g., registry-1.docker.io).
  • You don’t include the repository path (e.g., /artemla/cert-manager).
  • This is important — see the Docker section below for more details.

Our Setup

We’ve tested and validated this setup with:

  • Argo CD Version:v2.14.3
  • Argo CD Helm Chart Version:7.8.7
  • Helm CLI Version:v3.17.0

Additionally, we’ve confirmed compatibility with older versions of both Argo CD and Helm.

Now that we understand the differences, let’s move on to the actual setup!

Docker OCI: Setting Up a Private OCI Helm Repository with Argo CD

In this section, we’ll go through the full process of:

  1. Creating a Personal Access Token (PAT) in Docker Hub.
  2. Pulling the Cert-Manager v1.17.1 Helm chart from Jetstack.io.
  3. Pushing the chart to a private Docker Helm OCI registry.
  4. Integrating it into Argo CD and deploying an application from the private repository.
Fig. 4: Deploying a Mirrored Cert-Manager Helm Chart via Docker Private OCI Repository
Fig. 4: Deploying a Mirrored Cert-Manager Helm Chart via Docker Private OCI Repository

Step 1: Generate a Personal Access Token (PAT) in Docker Hub

First, navigate to Docker Hub and create a Personal Access Token (PAT).

Fig. 5: Docker GUI: Create PAT
Fig. 5: Docker GUI: Create PAT

Copy the login command with your PAT and execute it locally:

Bash / Shell
docker login -u artemla

Password:
Login Succeeded

Step 2: Pull the Cert-Manager Helm Chart from Jetstack

Now, let’s pull the Cert-Manager v1.17.1 Helm chart:

Bash / Shell
helm pull --version 1.17.1 --repo https://charts.jetstack.io cert-manager

After running this, you should see the Helm chart package in your directory:

ls 
cert-manager-v1.17.1.tgz

Step 3: Push the Helm Chart to a Private Docker Helm OCI Repository

Now, we push the Helm chart to our private Docker OCI registry:

Bash / Shell
helm push cert-manager-v1.17.1.tgz oci://registry-1.docker.io/artemla

Important Notes

– You only specify the registry (artemla), not the full path (/artemla/cert-manager).
– The chart name is automatically extracted from its metadata, so Docker will create the correct repository structure.

Check if the push was successful by looking at the Docker UI:

Fig. 6: Verifying Helm Chart Push to Private OCI Repository
Fig. 6: Verifying Helm Chart Push to Private OCI Repository

or by running:

Bash / Shell
helm pull oci://registry-1.docker.io/artemla/cert-manager --version v1.17.1

Make sure to set your repository to private under Docker Hub repository settings!

Step 4: Add the Private Docker OCI Helm Repository to Argo CD

4.1 Add via Argo CD UI

  1. Navigate to Argo CD → Settings → Repositories.
  2. Click + CONNECT REPO and enter the following details:
  • URL:registry-1.docker.io (⚠️ No /artemla at the end)
  • Enable OCI: (Make sure to check this option)

3. Click CONNECT.

Fig. 7: Adding a Docker Private OCI Helm Repository to Argo CD
Fig. 7: Adding a Docker Private OCI Helm Repository to Argo CD
Fig.8: Don’t forget enable OCI!
Fig.8: Don’t forget enable OCI!

Now you should see something like this:

Fig. 9: After successfully added
Fig. 9: After successfully added

4.2 Add via CLI (Imperative Approach)

Alternatively, you can add the repository using kubectl by creating a Kubernetes Secret:

YAML
apiVersion: v1
data:
  enableOCI: dHJ1ZQ==
  name: ZG9ja2VyLW9jaQ==
  password: ZG.......
  project: ZGVmYXVsdA==
  type: aGVsbQ==
  url: cmVnaXN0cnktMS5kb2NrZXIuaW8=
  username: YXJ0ZW1sYQ==
kind: Secret
metadata:
  annotations:
    managed-by: argocd.argoproj.io
  labels:
    argocd.argoproj.io/secret-type: repository
  name: repo-2984550025
  namespace: argocd
type: Opaque

For a declarative approach, we recommend using External Secrets Operator or Sealed Secrets for secret management.

Step 5: Deploy Cert-Manager from the Private OCI Repository in Argo CD GUI

  1. Navigate to Argo CD → Applications.
  2. Click + NEW APP and fill in the form as follows:
  • Repository URL:registry-1.docker.io
  • Chart Name:artemla/cert-manager
  • Version:v1.17.1

3. Click CREATE.

Fig. 10: Deploying Cert-Manager via Docker Private OCI Helm Repository
Fig. 10: Deploying Cert-Manager via Docker Private OCI Helm Repository

Argo CD should now show an “OutOfSync” status, meaning it can successfully pull the Helm chart from your private OCI registry.

Fig. 11: Argo CD Application Status After Deploying Cert-Manager
Fig. 11: Argo CD Application Status After Deploying Cert-Manager

Application YAML Example

This is what the corresponding Argo CD Application YAML looks like:

YAML
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: cert-manager
  namespace: argocd
spec:
  destination:
    namespace: cert-manager
    server: https://kubernetes.default.svc
  project: default
  source:
    chart: artemla/cert-manager
    repoURL: registry-1.docker.io
    targetRevision: v1.17.1
  sourceType: Helm

This works for both ApplicationSets and Umbrella Charts.
No need for the passCredentials parameter when using OCI repositories.

Step 6 (Optional): Deploying with ApplicationSets and an Umbrella Helm Chart

For dynamic deployments, you can use ApplicationSets with a Cluster Generator:

YAML

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: cert-manager
  namespace: argocd
spec:
  generators:
    - clusters:
        selector:
          matchLabels:
            cert-manager: enabled
        values:
          branch: main
  template:
    metadata:
      name: "{{name}}-cert-manager"
      annotations:
        argocd.argoproj.io/manifest-generate-paths: ".;.."

    spec:
      project: default
      sources:
        - repoURL: https://......
          path: "./cert-manager"
          targetRevision: "{{values.branch}}"

      destination:
        name: "{{name}}"
        namespace: "cert-manager"
      syncPolicy:
        syncOptions:
          - CreateNamespace=false
          - PruneLast=true

Or, if you’re working with Umbrella Helm Charts, here’s how you define it:

YAML
apiVersion: v2
name: cert-manager
description: Umbrella Chart for cert-manager
type: application
version: 0.0.1
dependencies:
  - name: artemla/cert-manager
    version: v1.17.1
    repository: "oci://registry-1.docker.io"

Next Up: Setting Up a Private OCI Helm Repository with GitLab

Now that we’ve successfully set up a private OCI Helm repository using Docker, in the next section, we’ll explore how to do the same with GitLab.

GitLab OCI: Setting Up a Private OCI Helm Repository with Argo CD

In this section, we will:

  1. Create an Access Token for a GitLab repository.
  2. Pull the Cert-Manager v1.17.1 Helm chart from Jetstack.io.
  3. Push the chart to a private GitLab Helm OCI registry.
  4. Integrate it into Argo CD and deploy an application from the private repository.
Fig. 12: Deploying a Mirrored Cert-Manager Helm Chart via GitLab Private OCI Repository
Fig. 12: Deploying a Mirrored Cert-Manager Helm Chart via GitLab Private OCI Repository

Step 1: Create a GitLab Access Token

Navigate to GitLab or your self-hosted GitLab instance.

  1. Go to Settings → Access Tokens in your repository.
  2. Create a Project Access Token with the necessary permissions.

like:

Fig. 13: GitLab GUI: Create Project Access Token
Fig. 13: GitLab GUI: Create Project Access Token

Step 2: Pull the Cert-Manager Helm Chart from GitHub

Run the following command to pull the Cert-Manager v1.17.1 Helm chart:

Bash / Shell
helm pull --version 1.17.1 --repo https://charts.jetstack.io cert-manager

After execution, verify that the chart package is in your directory:

ls 
cert-manager-v1.17.1.tgz

Step 3: Log in and Push the Helm Chart to a Private GitLab OCI Registry

Log in to the GitLab registry using the access token and push the Helm chart to the private GitLab OCI repository::

Bash / Shell
helm registry login registry.gitlab.your-domain.tech --username git
....

helm push cert-manager-v1.17.1.tgz oci://registry.gitlab.your-domain.tech/private/infrastructure-charts

To confirm the push was successful, try pulling the chart:

Bash / Shell
helm pull oci://registry.gitlab.your-domain.tech/private/infrastructure-charts/cert-manager --version v1.17.1

Step 4: Add the Private GitLab OCI Helm Repository to Argo CD

4.1 Add via Argo CD UI

  1. Navigate to Argo CD → Settings → Repositories.
  2. Click + CONNECT REPO and enter the following details:
  • URL:registry.gitlab.your-domain.tech
  • Enable OCI: Make sure this option is checked.

3. Click CONNECT.

Fig. 14: Adding a GitLab Private OCI Helm Repository to Argo CD
Fig. 14: Adding a GitLab Private OCI Helm Repository to Argo CD

4.2 Add via CLI (Imperative Approach)

You can also add the repository using kubectl by creating a Kubernetes Secret:

YAML
apiVersion: v1
data:
  enableOCI: dHJ1ZQ==
  name: aWl0cy1vY2k=
  password: Z.....
  project: ZGVmYXVsdA==
  type: aGVsbQ==
  url: c.....
  username: Z2l0
kind: Secret
metadata:
  annotations:
    managed-by: argocd.argoproj.io
  labels:
    argocd.argoproj.io/secret-type: repository
  name: repo-1906426995
  namespace: argocd
type: Opaque

For a declarative setup, it is recommended to use External Secrets Operator or Sealed Secrets for secret management.

Step 5: Deploy Cert-Manager from the Private OCI Repository in Argo CD

  1. Navigate to Argo CD → Applications.
  2. Click + NEW APP and fill in the form as follows:
  • Repository URL:registry.gitlab.your-domain.tech
  • Chart Name:private/infrastructure-charts/cert-manager
  • Version:v1.17.1

3. Click CREATE.

Argo CD should now show an “OutOfSync” status, indicating it successfully retrieved the Helm chart from the private OCI registry.

Fig. 15: Deploying Cert-Manager via GitLab Private OCI Helm Repository
Fig. 15: Deploying Cert-Manager via GitLab Private OCI Helm Repository

Application YAML Example

This is what the corresponding Argo CD Application YAML looks like:

YAML
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: cert-manager
  namespace: argocd
spec:
  destination:
    namespace: cert-manager
    server: https://kubernetes.default.svc
  project: default
  source:
    chart: private/infrastructure-charts/cert-manager
    repoURL: registry.gitlab.iits.tech
    targetRevision: v1.17.1

Next: Setting Up a Private OCI Helm Repository with Harbor

Now that we have successfully configured a private OCI Helm repository using GitLab, the next section will focus on Harbor.

Harbor OCI: Setting Up a Private OCI Helm Repository with Argo CD

In this section, we will:

  1. Create a Robot Account in Harbor.
  2. Pull the Cert-Manager v1.17.1 Helm chart from Jetstack.
  3. Push the chart to a private Harbor OCI registry.
  4. Integrate it into Argo CD and deploy an application from the private repository.
Fig. 16: Deploying a Mirrored Cert-Manager Helm Chart via Harbor Private OCI Repository
Fig. 16: Deploying a Mirrored Cert-Manager Helm Chart via Harbor Private OCI Repository

Step 1: Create a Robot Account in Harbor

  1. Open the Harbor UI and navigate to your project.
  2. Select Robot Accounts and create a new access token.
  3. Assign the necessary permissions, such as create, delete, list, and update for repositories.

Like:

Fig. 17: Create Robot Account
Fig. 17: Create Robot Account
Fig. 18: Create Robot Account (Part 2)
Fig. 18: Create Robot Account (Part 2)

Step 2: Pull the Cert-Manager Helm Chart from Jetstack

Download the Cert-Manager v1.17.1 Helm chart using Helm:

Bash / Shell
helm pull --version 1.17.1 --repo https://charts.jetstack.io cert-manager

After the command executes, confirm that the Helm chart is in your directory:

ls 
cert-manager-v1.17.1.tgz

Step 3: Log in and Push the Helm Chart to a Private Harbor OCI Registry

Log in to your Harbor registry using the Robot Account credentials and push the Helm chart to the private Harbor OCI repository::

Bash / Shell
helm registry login  registry.your-domain.cloud/projectname --username 'robot$project-harbor-oci..'
....

helm push cert-manager-v1.17.1.tgz oci://registry.your-domain.cloud/projectname

To verify the push, try pulling the chart:

Bash / Shell
helm pull oci://registry.your-domain.cloud/projectname/cert-manager --version v1.17.1

Step 4: Add the Private Harbor OCI Helm Repository to Argo CD

4.1 Add via Argo CD UI

  1. Navigate to Argo CD → Settings → Repositories.
  2. Click + CONNECT REPO and enter the following details:
  • URL:registry.your-domain.cloud/projectname
  • Enable OCI: Make sure this option is checked.

3. Click CONNECT.

Unlike Docker and GitLab, the project name is included in the URL.

Fig. 19: Connecting a Harbor Private OCI Helm Repository to Argo CD
Fig. 19: Connecting a Harbor Private OCI Helm Repository to Argo CD

4.2 Add via CLI (Imperative Approach)

You can also add the repository using kubectl by creating a Kubernetes Secret:

YAML
apiVersion: v1
data:
  enableOCI: dHJ1ZQ==....
  name: b2NpL.....
  password: Mk
  project: ZGVmYXVsdA==
  type: aGVsbQ==....
  url: cmVn
  username: cm9ib3Qkc....
kind: Secret
metadata:
  annotations:
    managed-by: argocd.argoproj.io
  labels:
    argocd.argoproj.io/secret-type: repository
  name: repo-1876401384
  namespace: argocd
type: Opaque

For a declarative setup, it is recommended to use External Secrets Operator or Sealed Secrets for secret management.

Step 5: Deploy Cert-Manager from the Private OCI Repository in Argo CD

  1. Navigate to Argo CD → Applications.
  2. Click + NEW APP and fill in the form as follows:
  • Repository URL:registry.your-domain.cloud/projectname
  • Chart Name:cert-manager
  • Version:v1.17.1

3. Click CREATE.

Unlike Docker or GitLab, in Harbor, the project name is explicitly included in the repository path. You just need add the Chart like:

Fig. 20: Deploying an Application via Harbor Private OCI Helm Repository in Argo CD
Fig. 20: Deploying an Application via Harbor Private OCI Helm Repository in Argo CD

Application YAML Example

This is what the corresponding Argo CD Application YAML looks like:

YAML
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: cert-manager
  namespace: argocd
spec:
  destination:
    namespace: cert-manager
    server: https://kubernetes.default.svc
  project: default
  source:
    chart: cert-manager
    repoURL: registry.your-domain.cloud/projectname
    targetRevision: v1.17.1

Final Thoughts

This guide covers how to set up private OCI Helm repositories in Docker, GitLab, and Harbor for Argo CD deployments.
By following this guide, your Argo CD Private OCI Helm Repository Setup will be optimized for security, automation, and scalability.

All examples work with Applications, ApplicationSets, and Umbrella Helm Charts.
For self-hosted projects, we personally recommend Harbor or GitLab as OCI registries.

This should help regardless of which private OCI registry you choose.

Thank You!

This blog post wouldn’t have been possible without the contributions and expertise of the following people:

Authors:

  • Alexander Hoeft
  • Artem Lajko

Engineering Support:

  • Philip Siemer
  • Daniel Schlosser

A huge thank you to everyone involved in making this guide as clear, practical, and valuable as possible!

Visit our other blogs!

FAQs:

  • What is the difference between a Helm repository and an OCI Helm repository?
  • How do I configure a private Helm chart repository in Argo CD?
  • Why should I use OCI Helm repositories instead of traditional Helm repositories?

Über den Autor

Alexander Hoeft
ArgoCDDockerGitLabGitOpsHarborHelm

Weiterlesen


  • iits-consulting is a Partner of T Cloud Public
    DevOps & CloudOps

    iits-consulting is a Partner of T Cloud Public

    23. Feb. 2026 · 4 min · Jenna Gockel
  • ingress-nginx is being retired: How to Migrate to Traefik with OAuth2 Proxy
    DevOps & CloudOps

    ingress-nginx is being retired: How to Migrate to Traefik with OAuth2 Proxy

    23. Feb. 2026 · 13 min · Alexander Hoeft
  • Grafana Helm Charts Are Moving on 30 Jan 2026
    DevOps & CloudOps

    Grafana Helm Charts Are Moving on 30 Jan 2026

    22. Jan. 2026 · 4 min · Yannick Reinhardt