> ## Documentation Index
> Fetch the complete documentation index at: https://docs.qodo.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Pull Qodo images and Helm charts through JFrog Artifactory

> Configure Artifactory remote and virtual repositories for Qodo images and the Helm chart, pull credentials, and Qodo Helm values.

* **Deployment model**: On-premises

Use your Artifactory Docker registry to cache Qodo container images and serve
them to your Kubernetes cluster. A remote repository connects to Qodo's
Replicated proxy. An optional virtual repository gives your clients one Docker
endpoint for that remote repository. A separate Helm OCI remote repository can
also cache the Qodo Helm chart.
For more information, see [Use Artifactory for pull-through proxy caching](https://docs.replicated.com/vendor/using-third-party-registry-proxy#use-artifactory-for-pull-through-proxy-caching).

The two connections use different credentials:

| Connection | Credential |
| - | - |
| Artifactory to the Qodo image proxy and chart registry | Your Qodo-issued Replicated license |
| Docker clients, Helm clients, and Kubernetes to Artifactory | Your Artifactory accounts and access tokens |

For more information, see [Use Artifactory for pull-through proxy caching](https://docs.replicated.com/vendor/using-third-party-registry-proxy#use-artifactory-for-pull-through-proxy-caching) and [Pull an image from a private registry](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/).

## Before you begin

Prepare:

* Your Qodo registry credentials and access to the Helm chart delivery channel
* Artifactory administration access and support for Docker remote and virtual repositories
* An HTTPS Docker endpoint trusted by your Docker clients and Kubernetes container runtimes
* Outbound HTTPS access from Artifactory to `artif-reg-self-hosted.codium.ai`, and to `artifacts-self-hosted.qodo.ai` if Artifactory also caches the chart
* Your Qodo namespace, Kubernetes context, chart package, and customer values

Configure private CA trust on the nodes if required. Use your existing
installation namespace and have your cluster administrator create it first if
needed.

With licensed registry delivery, the Helm chart is downloaded separately from
`oci://artifacts-self-hosted.qodo.ai/codium-stack/qodo-onprem/qodo-onprem`.
The chart registry and the image proxy are different hosts, so the Docker
remote repository can't serve the chart. Your Helm client or Argo CD needs
access to the chart registry, or to an Artifactory chart repository that
proxies it. Release bundles already include the chart. For more information,
see [Pull the Helm chart through Artifactory](#pull-the-helm-chart-through-artifactory).

Set the Kubernetes inputs in the shell you will use for the following steps:

```bash theme={null}
KUBE_CONTEXT="REPLACE_WITH_YOUR_CONTEXT"
NAMESPACE=qodo
```

The main Helm examples use a standard unpacked chart and these files:

| File | Purpose |
| - | - |
| `qodo-onprem/onprem-base.yaml` | Qodo's base values from the same chart release |
| `my-values.yaml` | Your existing customer configuration |
| `artifactory-values.yaml` | The image registry settings you create in step 5 |

If your standard release bundle keeps `onprem-base.yaml` at the top level,
use `-f onprem-base.yaml` in place of `-f qodo-onprem/onprem-base.yaml` in both
the render and install commands. Replace `my-values.yaml` if your customer
values file has a different name.

If your bundle contains `qodo-onprem.tgz` and a single editable values file,
keep the chart packaged. Complete steps 1–4 and use the packaged-bundle procedure below for configuration,
rendering, and installation. For more information, see
[Packaged single-values bundles](#packaged-single-values-bundles).

## 1. Create the remote repository

1. Go to **Administration** > **Repositories** > **Create a Repository**.
2. Select **Remote**, then **Docker**.
3. Configure these settings:

| Setting | Value |
| - | - |
| Repository key | `qodo-remote` |
| URL | `https://artif-reg-self-hosted.codium.ai` |
| User Name | Your Qodo account email |
| Password / Access Token | Your valid Replicated license ID |
| API version | V2 |
| Enable Token Authentication | Enabled |
| Store Artifacts Locally | Enabled |
| Offline | Disabled |
| Repository Layout | `simple-default` |
| Include Patterns | `**/*` |
| Exclude Patterns | Empty |

For more information, see [Remote repositories](https://docs.jfrog.com/artifactory/docs/remote-repositories).

4. Select **Test** and confirm that the connection succeeds, then create the
   repository.

Use the proxy host as the URL. Keep `/proxy/codium-stack/` in the image path,
rather than adding it to the remote repository URL. Customers using the new
Replicated Enterprise Portal can use a customer service-account token in the
Password / Access Token field. For more information, see [Use Artifactory for pull-through proxy caching](https://docs.replicated.com/vendor/using-third-party-registry-proxy#use-artifactory-for-pull-through-proxy-caching).

## 2. Add the remote to a virtual repository

You can reuse an existing Docker virtual repository or create one:

1. Open the same repository creation menu.
2. Select **Virtual**, then Docker.
3. Set the repository key to `qodo-virtual`.
4. Move `qodo-remote` into **Selected Repositories**.
5. Leave **Default Deployment Repository** unset and create the repository.

Images are stored in the remote repository's cache. A local Docker repository
is not required for this pull-through setup. For more information, see [Virtual repositories](https://docs.jfrog.com/artifactory/docs/virtual-repositories).

The examples below use repository-path access:

```text theme={null}
registry.example.com/qodo-virtual/proxy/codium-stack/<upstream-registry>/<image-path>:<tag>
```

Use **Set Me Up** in Artifactory to confirm your Docker hostname, port, and
access method. With a repository-specific hostname or port, the repository
key is already selected by that endpoint. Omit `/qodo-virtual` from the image
prefix in that case. For more information, see [Docker repository URL formats](https://docs.jfrog.com/artifactory/docs/additional-docker-information#docker-repository-url-formats).

## 3. Grant cache access and test a full pull

Create or reuse an Artifactory pull account. Grant it Read and Deploy/Cache
permissions on the underlying `qodo-remote` repository. Apply the permission
to the remote even when clients use `qodo-virtual`.

Read access alone can serve cached images but fails when Artifactory needs to
cache missing layers. The permissions UI may also select Annotate when you
enable Deploy/Cache. For more information, see [How to troubleshoot Docker image not found or manifest unknown errors through Artifactory](https://jfrog.com/help/r/artifactory-how-to-troubleshoot-docker-image-not-found-or-manifest-unknown-errors-through-artifactory).

Choose the BusyBox image from your release's image inventory, provided in
`CUSTOMER-VALUES.md` for standard bundles. It also supports the Kubernetes
check below. Copy the
part of its Qodo image reference after `/proxy/codium-stack/`, including the
upstream registry, repository path, and tag.

Replace the hostname, repository key, upstream image path, and tag below with
your endpoint and release's BusyBox reference. For a repository-specific
hostname or port, omit `/qodo-virtual`. Use the same complete image reference
in the test Pod and the same registry prefix in your Helm values.

```bash theme={null}
docker login registry.example.com --username qodo-puller
docker pull --platform linux/amd64 \
  registry.example.com/qodo-virtual/proxy/codium-stack/us-central1-docker.pkg.dev/codium-production/codium-repo-self-hosted/mirror/busybox:REPLACE_WITH_RELEASE_TAG
```

Enter the Artifactory access token at the password prompt. Use the same account
you intend Kubernetes to use. Require a full download, including an image or
layers that are not already cached. The connection test and a manifest lookup
alone do not establish cold-cache access.

## 4. Create the Kubernetes pull Secret

Create a Secret named `qodo-pull` in your Qodo namespace. Its type must be
`kubernetes.io/dockerconfigjson` and its data key must be `.dockerconfigjson`.

If your secrets controller owns `qodo-pull`, update its source with your
Artifactory Docker configuration and wait for synchronization. For more
information, see [Manage Qodo secrets with External Secrets Operator](https://docs.qodo.ai/on-prem/external-secrets.md).

For a manually managed Secret, save this as `qodo-pull-secret.yaml`. Replace
the namespace, registry host, and authentication value:

```yaml qodo-pull-secret.yaml theme={null}
apiVersion: v1
kind: Secret
metadata:
  name: qodo-pull
  namespace: qodo
type: kubernetes.io/dockerconfigjson
stringData:
  .dockerconfigjson: |
    {
      "auths": {
        "registry.example.com": {
          "auth": "REPLACE_WITH_BASE64_OF_ARTIFACTORY_USERNAME_COLON_TOKEN"
        }
      }
    }
```

The registry key is the hostname and optional port, without the repository
path. The `auth` value is base64 of `username:access-token`. The surrounding
JSON remains plain text under `stringData`; Kubernetes encodes the Secret's
data. A Docker configuration
containing only `credsStore` or a credential-helper reference cannot supply
the credential to Kubernetes. For more information, see [Pull an image from a private registry](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/).

Keep this credential file private and apply it through your approved process:

```bash theme={null}
chmod 600 qodo-pull-secret.yaml
kubectl --context "$KUBE_CONTEXT" -n "$NAMESPACE" apply -f qodo-pull-secret.yaml
```

Keep credentials out of Helm values and version control. The Secret name is
fixed in this packaging; changing
`global.pullSecret` does not rename the references.

## 5. Configure the Helm values

Save this as `artifactory-values.yaml`, or download it from the
[Artifactory values file](https://docs.qodo.ai/examples/on-prem/artifactory-values.yaml). Replace the
example prefix with the one used for your successful Docker pull:

```yaml artifactory-values.yaml theme={null}
global:
  imageProxyPrefix: registry.example.com/qodo-virtual/proxy/codium-stack/
  replicated:
    dockerconfigjson: ""
```

| Docker access method | Example `global.imageProxyPrefix` |
| - | - |
| Repository path | `registry.example.com/qodo-virtual/proxy/codium-stack/` |
| Repository-specific hostname | `qodo-virtual.registry.example.com/proxy/codium-stack/` |
| Repository-specific port | `registry.example.com:5443/proxy/codium-stack/` |

`imageProxyPrefix` contains no URL scheme. Preserve the complete image path
after `/proxy/codium-stack/`, including the upstream registry name. If you
pull directly through `qodo-remote`, use that key instead of `qodo-virtual`.

Override only `global.replicated.dockerconfigjson`. A licensed chart download
injects a Docker credential for the Qodo proxy. Clearing that field makes
workloads and setup Jobs use your `qodo-pull` Secret. Retain the other
Replicated license fields. Create `qodo-pull` for Artifactory even when your
chart was downloaded with a Replicated license.

Leave `global.composeImageProxyPrefix` enabled. Load the Artifactory values
after `onprem-base.yaml` and your existing customer values.

## 6. Verify before installing

Render the exact chart and values you will deploy. The output can contain
Secrets, so keep it private:

```bash theme={null}
umask 077
helm template qodo ./qodo-onprem --namespace "$NAMESPACE" \
  -f qodo-onprem/onprem-base.yaml \
  -f my-values.yaml \
  -f artifactory-values.yaml > qodo-artifactory-rendered.yaml
```

Open `qodo-artifactory-rendered.yaml`. Confirm every container, init
container, and setup Job uses your Artifactory image prefix and `qodo-pull`.
Resolve any remaining Qodo proxy references or
vendor pull-secret names before installing.

Save this as `qodo-artifactory-pull-check.yaml`. Replace the namespace and
`image` with the exact image reference you successfully pulled in step 3:

```yaml qodo-artifactory-pull-check.yaml theme={null}
apiVersion: v1
kind: Pod
metadata:
  generateName: qodo-artifactory-pull-check-
  namespace: qodo
spec:
  restartPolicy: Never
  imagePullSecrets:
    - name: qodo-pull
  containers:
    - name: pull-check
      image: registry.example.com/qodo-virtual/proxy/codium-stack/us-central1-docker.pkg.dev/codium-production/codium-repo-self-hosted/mirror/busybox:REPLACE_WITH_RELEASE_TAG
      imagePullPolicy: Always
      command: ["/bin/sh", "-c", "echo QODO_ARTIFACTORY_PULL_OK"]
```

Create a fresh test Pod so a previous successful check cannot be reused:

```bash theme={null}
kubectl --context "$KUBE_CONTEXT" -n "$NAMESPACE" create \
  -f qodo-artifactory-pull-check.yaml
```

Replace `REPLACE_WITH_CREATED_POD_NAME` with the Pod name printed by the
create command, then wait for completion and read its output:

```bash theme={null}
kubectl --context "$KUBE_CONTEXT" -n "$NAMESPACE" wait \
  --for=jsonpath='{.status.phase}'=Succeeded pod/REPLACE_WITH_CREATED_POD_NAME \
  --timeout=120s
kubectl --context "$KUBE_CONTEXT" -n "$NAMESPACE" logs REPLACE_WITH_CREATED_POD_NAME
```

Require the Pod to complete and print `QODO_ARTIFACTORY_PULL_OK`. Remove the
test Pod through your normal cluster workflow after verification.

| Failure | Check |
| - | - |
| Authentication error or HTTP 401 | Artifactory username/token and the registry host in `qodo-pull`; separately check the upstream Replicated license |
| HTTP 403 on an uncached image | Read and Deploy/Cache permissions on `qodo-remote` |
| Image or manifest not found | Repository key, preserved `/proxy/codium-stack/` path, image path, and tag |
| Certificate or TLS handshake error | Docker endpoint, certificate hostname, and CA trust on the affected client or node |

For fully offline operation, cache all image layers for your exact release and
enabled components before disconnecting. Include init containers and setup
Jobs. If Artifactory serves the chart, pull that chart version through
Artifactory too. A remote repository caches downloads on demand; a manifest
inventory alone does not make those images available offline.

## 7. Install with the verified values

Use the same chart and all three values files from the render check. Keep the
Artifactory override last for installation and every subsequent upgrade:

```bash theme={null}
helm upgrade --install qodo ./qodo-onprem \
  --kube-context "$KUBE_CONTEXT" --namespace "$NAMESPACE" \
  -f qodo-onprem/onprem-base.yaml \
  -f my-values.yaml \
  -f artifactory-values.yaml
```

For installations with additional component overlays, retain those files in
their existing order before `artifactory-values.yaml`. Include the same files
in the render check and installation command.

## Packaged single-values bundles

Use this procedure when your delivery includes `qodo-onprem.tgz` and one
editable customer values file. Keep the chart packaged. Do not add a base
values file or a separate Artifactory overlay to this format.

In the existing `global` section of your customer values file, set these
fields. Replace the example prefix with the registry prefix from your
successful Docker pull. Merge these fields into the existing mapping and
retain all other settings, including other Replicated license fields:

```yaml values-example.yaml (registry settings) theme={null}
global:
  imageProxyPrefix: registry.example.com/qodo-virtual/proxy/codium-stack/
  replicated:
    dockerconfigjson: ""
```

Use your bundle's actual customer values filename in place of
`values-example.yaml`. Render the packaged chart with that file:

```bash theme={null}
umask 077
helm template qodo ./qodo-onprem.tgz --namespace "$NAMESPACE" \
  -f values-example.yaml > qodo-artifactory-rendered.yaml
```

Confirm every image uses your Artifactory prefix and every pull-secret
reference selects `qodo-pull`. Run the Kubernetes pull check in step 6 before
installing. Use the same packaged chart and edited values file for
installation and subsequent upgrades:

```bash theme={null}
helm upgrade --install qodo ./qodo-onprem.tgz \
  --kube-context "$KUBE_CONTEXT" --namespace "$NAMESPACE" \
  -f values-example.yaml
```

## Pull the Helm chart through Artifactory

Use this procedure when you install from Qodo's licensed Helm registry and
your Helm client or Argo CD can't reach `artifacts-self-hosted.qodo.ai`
directly. Release bundles include the chart and don't need it.

### Create the chart remote repository

1. Go to Administration > Repositories > Create a Repository.
2. Select Remote, then **Helm OCI**.
3. Configure these settings:

| Setting | Value |
| - | - |
| Repository key | `qodo-helm-remote` |
| URL | `https://artifacts-self-hosted.qodo.ai` |
| User Name | Your Qodo account email |
| Password / Access Token | Your valid Replicated license ID |
| Enable Token Authentication | Enabled |
| Offline | Disabled |
| Include Patterns | `**/*` |
| Exclude Patterns | Empty |

4. Select Test and confirm that the connection succeeds, then create the
   repository.

Use the chart registry host as the URL. Keep `codium-stack/qodo-onprem/` in
the chart path, rather than adding it to the remote repository URL. Select
Helm OCI, not the legacy Helm package type. A legacy Helm repository can't
proxy an OCI registry. For more information, see [Kubernetes Helm chart repositories](https://docs.jfrog.com/artifactory/docs/kubernetes-helm-chart-repositories).

You can add `qodo-helm-remote` to a Helm OCI virtual repository, for example
`qodo-helm-virtual`. A virtual repository holds one package type, so you
can't add the chart remote to `qodo-virtual`. If Qodo issues a new license
ID, update the password on both remote repositories.

### Limit access to the chart

Replicated adds your license values to the chart when Artifactory downloads
it. The cached chart contains your license ID and
`global.replicated.dockerconfigjson`, a credential for the Qodo image proxy.
For more information, see [Helm global.replicated values schema](https://docs.replicated.com/vendor/helm-install-values-schema).

Grant Read and Deploy/Cache permissions on `qodo-helm-remote` only to the
account that installs Qodo, such as your Helm or Argo CD account. As with
images, Read access alone can't cache a chart version that isn't stored yet.
The Kubernetes pull account in `qodo-pull` doesn't need chart access. Don't
add the chart repository to a virtual repository that other teams can read.

### Pull and install the chart

Use Set Me Up on the chart repository to confirm the hostname and access
method. With repository-path access, the chart reference includes the
repository key:

```text theme={null}
oci://registry.example.com/qodo-helm-virtual/codium-stack/qodo-onprem/qodo-onprem
```

With a repository-specific hostname or port, omit `/qodo-helm-virtual` from
the chart reference. Replace the hostname, repository key, and chart version
below with your values:

```bash theme={null}
helm registry login registry.example.com --username qodo-deployer
helm pull oci://registry.example.com/qodo-helm-virtual/codium-stack/qodo-onprem/qodo-onprem \
  --version REPLACE_WITH_CHART_VERSION --untar
```

Enter the Artifactory access token at the password prompt. The command
extracts the chart to `qodo-onprem/`, including `qodo-onprem/onprem-base.yaml`.
Use that directory for the render check in step 6 and the installation in
step 7, with `artifactory-values.yaml` last. The chart package includes its
dependencies, so Helm needs no other chart repository.

For Argo CD, register the Artifactory hostname as the chart repository and
add the repository key to the chart path. For more information, see
[Configure repository access and the Application](https://docs.qodo.ai/on-prem/argocd.md#3-configure-repository-access-and-the-application).

## Next steps

* [Deploy Qodo using Helm](https://docs.qodo.ai/on-prem/qodo-on-prem-helm-chart-overview.md): Continue with your customer values and Artifactory override.
* [Deploy Qodo with Argo CD](https://docs.qodo.ai/on-prem/argocd.md): Register your chart repository and deploy with the Argo CD profile.
* [Helm chart configuration reference](https://docs.qodo.ai/on-prem/on-prem-helm-chart-reference.md): Review the supported image and installation values.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.