# How to set up pull-through from Chainguard's container registry to Artifactory

URL: https://chainguard-docs-preview-git-athena-mention.chainguard.app/chainguard/containers/registry/pull-through-guides/artifactory-containers-pull-through.md
Last Modified: October 8, 2026
Tags: Chainguard Containers

Tutorial outlining how to set up a remote Artifactory repository to pull images through Chainguard's container registry.


Organizations can route container image pulls through Artifactory to centralize artifact management, enforce policy, and integrate Chainguard Containers into existing CI/CD workflows. You can configure Artifactory as a pull-through cache by setting up a remote repository pointed at [Chainguard's container registry](/chainguard/containers/registry/overview/).

This tutorial outlines how to set up remote repositories with [JFrog Artifactory](https://jfrog.com/artifactory/). Specifically, it goes over how to set up one repository you can use as a pull-through cache for Chainguard's public [Free containers](/chainguard/containers/concepts/container-categories/#free-containers) and another you can use for [Production containers](/chainguard/containers/concepts/container-categories/#production-containers) originating from a private Chainguard repository. It also outlines how you can use one of Artifactory's [virtual repositories](https://jfrog.com/help/r/jfrog-artifactory-documentation/virtual-repositories) as a pull-through cache to access resources from multiple remote repositories in a single location.

## Prerequisites

To complete this tutorial, you need the following:

* Administrative privileges over an Artifactory instance. If you're interested in testing out this configuration, you can set up a trial instance on the [JFrog Artifactory landing page](https://jfrog.com/artifactory/).
* Docker installed on your local machine. Refer to [the official documentation](https://docs.docker.com/engine/install/) to set this up.

Part of this guide assumes you have access to a private registry provided by Chainguard with one or more Production container images. If you don't already have access to these, you can [contact our sales team](https://www.chainguard.dev/contact?utm_source=cg-academy&utm_medium=referral&utm_campaign=dev-enablement). To complete this portion, you will also need the following:

* Permissions to pull container images from your organization's private Chainguard registry. At minimum, you must be granted the `registry.pull` role, but other built-in roles like `owner`, `editor`, or `viewer` will also work. Refer to our guide on [Built-in roles and capabilities reference](/platform/administration/iam-organizations/roles-role-bindings/capabilities-reference/#pull-token-creator-roles) for more details.
* `chainctl`, Chainguard's command line interface tool, installed on your local machine. To set this up, follow our [installation guide for `chainctl`](/platform/chainctl-usage/how-to-install-chainctl/).

## Setting up Artifactory as a pull-through cache for free containers

Chainguard's Free Containers are free to use, publicly available, and always represent versions tagged as `:latest`.

To set up a remote repository in Artifactory from which you can pull Chainguard Free Containers:

1. Log in to the JFrog platform.
2. Select the **Administration** tab near the top of the screen.
3. Select **Repositories** from the left-hand navigation menu.
4. On the Repositories page, click **Create a Repository**.
5. Select the **Remote** option.
6. In the **Select Package Type** window, select **Docker**.

This takes you to a **Basic** configuration tab where you can enter the following details for your new remote repository:

* **Repository Key** — This is the name used to refer to your repository. You can choose whatever name you like here, but this guide's examples use the name `cgr-public`.
* **URL** — This must be set to `https://cgr.dev/`. This field **must not** include additional path components — setting it to something like `https://cgr.dev/chainguard/` will cause pulls to fail with a `manifest unknown` error. To shorten the pull path, use the **Project ID** field described below instead.
* **Project ID** — Optional. If you set this to `chainguard`, Artifactory prepends that path segment to upstream requests and your users can omit it from their pull commands. Leave it empty to keep the `chainguard/` prefix in the pull path, as this guide's examples do.
* **Include Patterns** — Ensure that you use the default value (`**/*`) in this field.
* **Enable Token Authentication** — Ensure this setting (under **Docker Settings**) is enabled. This is required, as you must authenticate to the remote repository in order to pull Chainguard Containers through it.
* **Block Mismatching Mime Types** — In the **Advanced** configuration tab, ensure that this option is checked.

Following that, click **Create Remote Repository**. Next, you can test that you're able to pull a Chainguard Free Container through the remote repository.

### Testing pull-through of a Chainguard free container

Before testing whether you're able to pull Chainguard's Free Containers through the remote Artifactory repository, you must retrieve a token generated by Artifactory for your remote repository. Expand the following section to retrieve a token and authenticate:

**JFrog Artifactory Token Retrieval**


<ol>
  <li>On the Repositories page, find your repository.</li>
  <li>Hover your cursor over the repository's row and click the ellipsis (<strong>⋯</strong>) all the way to the right.</li>
  <li>Select <strong>Set me up</strong>.</li>
  <li>Click the <strong>Generate Token &amp; Create Instructions</strong> button.</li>
</ol>

<p>The resulting window contains two tabs labeled <strong>Configure</strong> and <strong>Pull</strong>, each with certain commands and details you can copy.</p>

<p>In the <strong>Configure</strong> tab, copy the 64-character token, and then run a <code>docker login</code> command like the following on your local machine:</p>

<pre><code class="language-shell">docker login -u &lt;linky@chainguard.dev&gt; &lt;my-project&gt;.jfrog.io</code></pre>

<p>Be sure to replace the example username and Artifactory instance name in this command. The username following the <code>-u</code> flag must be the email or username associated with your JFrog Artifactory account, while you must replace <code>&lt;my-project&gt;</code> with the name of the Artifactory project where you created the remote repository. If you aren't sure of the name of your project, you can find it in the <code>docker login</code> command below the token you just copied.</p>

<p>At the <code>Password:</code> prompt, paste the token you copied previously and press <code>ENTER</code>.</p>




After running the `docker login` command, you will be able to pull a Chainguard Free Container through Artifactory. The following example pulls the `go` container image:

```sh
docker pull <my-project>.jfrog.io/cgr-public/chainguard/go
```

If you set **Project ID** to `chainguard` when creating the repository, omit that segment:

```sh
docker pull <my-project>.jfrog.io/cgr-public/go
```

Be sure the `docker pull` command you run includes the name of your project as well as your own repository key in place of `cgr-public`, if different.

## Setting up Artifactory as a pull-through cache for production containers

Chainguard's Production images are enterprise-ready container images that come with patch Service Level Agreements (SLAs) and features such as [Federal Information Processing Standard](/platform/fips/fips-images/) (FIPS) readiness. The process for setting up an Artifactory repository that you can use as a pull-through cache for Chainguard Production Containers is similar to the one outlined previously for Free Containers, but with a few extra steps.

To get started, create [a pull token](/chainguard/containers/registry/authenticating/#authenticating-with-a-pull-token) for your organization's registry. Pull tokens are longer-lived tokens that can be used to pull Chainguard Containers from other environments that don't support OIDC, such as some CI environments, Kubernetes clusters, or registry mirroring tools like Artifactory.

To create a pull token with `chainctl`, run the following command:

```sh
chainctl auth configure-docker --pull-token
```

`chainctl` uses your organization automatically when you belong to only one. If you have access to more than one, add `--parent <organization>`, replacing `<organization>` with the name or ID you want to use.

> **Note**: You can find your Chainguard organization's name or ID by running `chainctl iam organizations list -o table`.

This command returns a `docker login` command like the following:

```output
. . .

    docker login "cgr.dev" --username "<identity-id>" --password "<pull-token>"
```

Record the values for `<identity-id>` and `<pull-token>` as you'll need these credentials when you configure a new remote Artifactory repository for pulling through Production Containers.

After noting your credentials, you can begin setting up an Artifactory repository from which you can pull Chainguard Production Containers. This process is similar to the one outlined previously:

1. Log in to the JFrog platform.
2. Select the **Administration** tab near the top of the screen.
3. Select **Repositories** from the left-hand navigation menu.
4. On the Repositories page, click **Create a Repository**.
5. Select the **Remote** option.
6. In the **Select Package Type** window, select **Docker**.

Next, enter the following details for your new remote repository in the **Basic** configuration tab:

* **Repository Key** — Choose whatever name you like here, but this guide's examples use the name `cgr-private`.
* **URL** — This must be set to `https://cgr.dev/`. This field **must not** include additional path components — setting it to something like `https://cgr.dev/<organization>/` will cause pulls to fail with a `manifest unknown` error. To remove the organization from the pull path, use the **Project ID** field described below instead.
* **Project ID** — Optional. Set this to your organization's name (for example, `example.com`) and Artifactory prepends it to upstream requests, letting your users omit it from their pull commands. Because this field is set per repository, you need one remote repository per Chainguard organization if you pull from more than one.
* **User Name** — Enter the `<identity-id>` value you noted from the `docker login` command.
* **Password / Access Token** — Enter the `<pull-token>` value you noted from the `docker login` command.
* **Include Patterns** — Ensure that you use the default value (`**/*`) in this field.
* **Enable Token Authentication** — Ensure this setting (under **Docker Settings**) is enabled. This is required, as you must authenticate to the remote repository in order to pull Chainguard Containers through it.
* **Block Mismatching Mime Types** — In the **Advanced** configuration tab, ensure that this option is checked.

Finally, click **Create Remote Repository**. You can then move on to testing that you're able to pull Chainguard Production container images through this remote repository.

### Testing pull-through of a Chainguard production container

As with the `cgr-public` repository example, you must retrieve a token generated by Artifactory for your repository before testing whether you're able to pull Chainguard Production container images through the remote repository you just created. Expand the following section to retrieve a token and authenticate:

**JFrog Artifactory Token Retrieval**


<ol>
  <li>On the Repositories page, find your repository.</li>
  <li>Hover your cursor over the repository's row and click the ellipsis (<strong>⋯</strong>) all the way to the right.</li>
  <li>Select <strong>Set me up</strong>.</li>
  <li>Click the <strong>Generate Token &amp; Create Instructions</strong> button.</li>
</ol>

<p>The resulting window contains two tabs labeled <strong>Configure</strong> and <strong>Pull</strong>, each with certain commands and details you can copy.</p>

<p>In the <strong>Configure</strong> tab, copy the 64-character token, and then run a <code>docker login</code> command like the following on your local machine:</p>

<pre><code class="language-shell">docker login -u &lt;linky@chainguard.dev&gt; &lt;my-project&gt;.jfrog.io</code></pre>

<p>Be sure to replace the example username and Artifactory instance name in this command. The username following the <code>-u</code> flag must be the email or username associated with your JFrog Artifactory account, while you must replace <code>&lt;my-project&gt;</code> with the name of the Artifactory project where you created the remote repository. If you aren't sure of the name of your project, you can find it in the <code>docker login</code> command below the token you just copied.</p>

<p>At the <code>Password:</code> prompt, paste the token you copied previously and press <code>ENTER</code>.</p>




After running the `docker login` command, you will be able to pull Chainguard Production Containers through Artifactory. The following example pulls the `chainguard-base` image if your organization has access to it:

```sh
docker pull <my-project>.jfrog.io/cgr-private/<organization>/chainguard-base:latest
```

If you set **Project ID** to your organization's name when creating the repository, omit the organization from the pull path:

```sh
docker pull <my-project>.jfrog.io/cgr-private/chainguard-base:latest
```

Be sure the `docker pull` command you run includes the name of your Artifactory project and the name of your organization's registry. Additionally, if you entered a different repository key in the setup section, use it in place of `cgr-private`.

## Setting up an Artifactory virtual repository as a pull-through cache

Artifactory allows you to create what it refers to as [*virtual repositories*](https://jfrog.com/help/r/jfrog-artifactory-documentation/virtual-repositories). A virtual repository is a collection of one or more repositories (such as local, remote, or other virtual repositories) that have the same package type. The benefit of this is that you can access resources from multiple locations using a single logical URL.

You can also use a virtual repository as a pull-through cache. To set this up, create a new virtual repository:

1. Navigate to the **Repositories** tab.
2. Click **Create a Repository**.
3. Select the **Virtual** option.
4. In the **Select Package Type** window, select **Docker**.

When you reach the **New Virtual Repository** page, enter a key of your choosing into the **Repository Key** field. This guide's examples refer to this repository as `cgr-virt`.

Next, you must select existing repositories to include within this virtual repository. To keep things simple, this guide uses the `cgr-public` and `cgr-private` repositories created previously:

1. Locate the **Repositories** section in the **Basic** configuration tab.
2. Select the repositories you want to add from the **Available Repositories** by clicking their respective checkboxes.
3. Click the right-pointing chevron to move them to **Selected Repositories**.
4. Click **Create Virtual Repository**.

With that, you can retrieve the token and `docker login`.

### Testing pull-through with a virtual repository

As with the previous examples, you must retrieve a token generated by Artifactory before testing whether you're able to pull Chainguard Containers through the virtual repository. Expand the following section to retrieve a token and authenticate:

**JFrog Artifactory Token Retrieval**


<ol>
  <li>On the Repositories page, find your repository.</li>
  <li>Hover your cursor over the repository's row and click the ellipsis (<strong>⋯</strong>) all the way to the right.</li>
  <li>Select <strong>Set me up</strong>.</li>
  <li>Click the <strong>Generate Token &amp; Create Instructions</strong> button.</li>
</ol>

<p>The resulting window contains two tabs labeled <strong>Configure</strong> and <strong>Pull</strong>, each with certain commands and details you can copy.</p>

<p>In the <strong>Configure</strong> tab, copy the 64-character token, and then run a <code>docker login</code> command like the following on your local machine:</p>

<pre><code class="language-shell">docker login -u &lt;linky@chainguard.dev&gt; &lt;my-project&gt;.jfrog.io</code></pre>

<p>Be sure to replace the example username and Artifactory instance name in this command. The username following the <code>-u</code> flag must be the email or username associated with your JFrog Artifactory account, while you must replace <code>&lt;my-project&gt;</code> with the name of the Artifactory project where you created the remote repository. If you aren't sure of the name of your project, you can find it in the <code>docker login</code> command below the token you just copied.</p>

<p>At the <code>Password:</code> prompt, paste the token you copied previously and press <code>ENTER</code>.</p>




After retrieving your token and logging into `docker`, you will be able to pull Chainguard Containers through the Artifactory virtual repository.

To pull a public image, you would run a command like the following, which pulls the public `mariadb` image:

```sh
docker pull <my-project>.jfrog.io/cgr-virt/chainguard/mariadb:latest
```

To pull a Production Container, replace `chainguard` with the name of your organization's registry. The following example pulls the `chainguard-base` image if your organization has access to it:

```sh
docker pull <my-project>.jfrog.io/cgr-virt/<organization>/chainguard-base:latest
```

For both of these commands, be sure the `docker pull` command you run includes the name of your Artifactory project and the name of your organization's registry. Also, if you used a different repository key, substitute it for `cgr-virt` in the previous commands.

> **Note**: Take care when aggregating remote repositories that each set a **Project ID**. If both the free and private remotes strip their path prefixes, image names from different sources collapse into the same namespace within the virtual repository — for example, both `chainguard/go` and `<organization>/go` would resolve as `go`, and the virtual repository's resolution order determines which one you get.

## Debugging pull-through from Chainguard’s registry to Artifactory

If you run into issues when trying to pull images from Chainguard's container registry to Artifactory, ensure the following requirements are met:

* Ensure that all Containers [network requirements](/chainguard/containers/registry/network-requirements/) are met.
* If you attempt to pull a nonexistent image via pull-through, Artifactory will also make calls to `chainguard.dev` and `www.chainguard.dev`. Calls to these domains should not occur when pulling a valid image.
* When configuring a remote Artifactory repository, ensure that the **URL** field is set to `https://cgr.dev/`. This field **must not** contain additional components. Adding a path such as `https://cgr.dev/<organization>/` produces a `manifest unknown: The named manifest is not known to the registry` error, because Artifactory ignores the path portion of a Docker remote's URL. If your goal is to shorten the pull path, set the repository's **Project ID** to your organization's name instead.
* You can troubleshoot by running `docker login` from another node (using the Artifactory pull token credentials) and then trying to pull a Container from `cgr.dev/chainguard/<image name>` or `cgr.dev/<organization>/<image name>`.
* It may help to [clear the Artifactory cache](https://jfrog.com/help/r/artifactory-cleanup-best-practices/clearing-an-oversized-cache).
* Your Artifactory repository may be misconfigured. In this case, create and configure a new remote Artifactory repository to test with.

## Learn more

If you haven't already done so, you may find it useful to review our [Registry overview](/chainguard/containers/registry/overview/) to learn more about the Chainguard container registry. You can also learn more about Chainguard Containers by referring to our [Containers documentation](/chainguard/containers/overview/). If you'd like to learn more about JFrog Artifactory, refer to the [official Artifactory documentation](https://jfrog.com/help/r/jfrog-artifactory-documentation).

