How to Pull Packages from Chainguard Package Repositories through Artifactory

Tutorial for setting up remote Artifactory repositories as pull-through caches for apk packages from Chainguard's package repositories.
  9 min read

This tutorial details how to set up remote Alpine package (apk) repositories with JFrog Artifactory, which can provide pull-through caches for Chainguard package repositories. Specifically, this guide walks you through how to set up remote Artifactory repositories to serve as pull-through caches for a Chainguard Private APK Repository as well as Chainguard’s public package repositories. The guide also outlines how to configure a container image build to pull APK packages from these remote repositories using tokens generated by Artifactory.

Prerequisites

In order to complete this tutorial, you need the following:

  • Administrative privileges over an Artifactory instance.
  • chainctl
  • Administrative privileges within your Chainguard organization to create role-bindings (role_bindings.create); this capability is available to users with the owner role.

Creating a Chainguard Pull Token for Remote Repository Authentication

When configuring an Artifactory remote repository to function as a pull-through cache for packages from a Chainguard private APK repository, the remote repository must authenticate to Chainguard. This section outlines the steps necessary to create a Chainguard pull token and configure the required permissions to access your Chainguard organization’s private APK repository:

Set your Chainguard organization identifier as an environment variable. Replace the example.org placeholder with your organization’s name as it appears in the Chainguard Console:

export CHAINGUARD_ORG=example.org

Next, generate a pull token:

chainctl auth pull-token --parent=${CHAINGUARD_ORG} -o env

The command outputs the credentials as export commands you can run to set them as environment variables:

export CHAINGUARD_IDENTITY_ID=<id>
export CHAINGUARD_TOKEN=<token>

Run the first of these commands to create an environment variable for the identity:

export CHAINGUARD_IDENTITY_ID=<id>

Be sure to note both the identity and token values to use when you create a remote Artifactory repository in the next section.

With the environment variables in place, create a role binding to bind the pull token identity the apk.pull role:

  chainctl iam role-bindings create \
    --parent=${CHAINGUARD_ORG} \
    --identity=${CHAINGUARD_IDENTITY_ID} \
    --role=apk.pull

This enables the identity to download packages from the private APK repository of the organization.

Setting Up a Pull-Through Cache for a Private APK Repository

Now that you have an identity with permissions to do so, you can set up a remote Artifactory repository to reach your private APK repository.

To set up the remote repository:

  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 the Create a Repository button.
  5. Select the Remote option.
  6. In the Select Package Type window, select Alpine.

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

  • Repository Key — This is a name used to identify your remote repository, for example cg-private.
  • URL — This must be set to https://apk.cgr.dev/${CHAINGUARD_ORG}, but with your organization’s actual name in place of ${CHAINGUARD_ORG}. For example, if your organization is named example use https://apk.cgr.dev/example.
  • User Name — This is used by Artifactory to authenticate to Chainguard and access your private APK repository. Use the pull token identity ID value you set to the CHAINGUARD_IDENTITY_ID variable.
  • Password / Access Token — This is used along with the user name to authenticate to Chainguard. Here, enter the value from CHAINGUARD_TOKEN.

Then, navigate to the Advanced configuration tab and enter the following details:

  • Disable URL Normalization — This must be enabled because, in some cases, the normalization will invalidate the URLs that packages are served from.

Click the Create Remote Repository button to create the remote repository and return to the Repositories page.

Note: For more information on how to set up a remote repository in Artifactory, refer to the official documentation.

Generating a token for the remote repository

Before testing whether you’re able to pull packages through the remote Artifactory repository, you must retrieve a token generated for it by Artifactory.

  1. On the Repositories page, find your repository.
  2. Hover your cursor over the repository’s row and click the ellipsis () all the way to the right.
  3. Select Set me up.
  4. Click the Generate Token & Create Instructions button.
  5. Copy or take note of the token generated for your repository.

With this token in hand, run the following export command to create an environment variable, replacing my-token with the token you noted down. You will use this environment variable in the following section as you test out the remote repository:

export CG_PRIVATE_TOKEN=my-token

Additionally, create two more environment variables to hold your Artifactory username and server name:

export ARTIFACTORY_USERNAME=my-user-profile
export ARTIFACTORY_SERVER_NAME=my-artifactory-hostname

If you aren’t sure of these values, you can find them in the command from the Set Up An Alpine Client window where you retrieved the token:

sudo sh -c "echo 'https://linky:<TOKEN>@example-server-name.jfrog.io/artifactory/cg-private/<BRANCH>/<REPOSITORY>'" >> /etc/apk/repositories

In this example, the Artifactory username is linky and the hostname is example-hostname.

Note: If your Artifactory username is an email address, you must percent-encode the @ sign, as in export ARTIFACTORY_USERNAME=linky%40example.com. Here, the Artifactory username is linky@example.com, but it must be entered into the environment variable as linky%40example.com.

Testing pull-through from private APK repository

This section outlines how to build a container image using a Chainguard image as a base and configure it to pull packages from the private APK repositories through your remote Artifactory repository.

Open a terminal and create a Dockerfile:

cat > Dockerfile <<EOF
FROM cgr.dev/chainguard/python:latest-dev
USER root
RUN cp /etc/apk/repositories /etc/apk/repositories.disabled
RUN echo 'https://$ARTIFACTORY_USERNAME:$CG_PRIVATE_TOKEN@$ARTIFACTORY_SERVER_NAME.jfrog.io/artifactory/cg-private/' > /etc/apk/repositories
RUN apk add sed
USER nonroot
EOF

This Dockerfile uses the python:latest-dev image. You don’t have to use this particular image, but because we are using the apk command to install a package from cgr-private in this Dockerfile, you should use a Chainguard container image that has this package manager available.

Note that this Dockerfile renames the default /etc/apk/repositories file. This isn’t necessary, but doing so allows you to ensure that you’re actually downloading packages from the remote Artifactory repositories instead of the default ones.

Additionally, be aware that there are limitations to what packages are available from your organization’s private APK repository. For instance, your organization may not have access to the sed package. Refer to our private APK repository documentation for more information.

After creating the Dockerfile, build the image. Here, we tag the image ar-build:

docker build -t ar-build .

This command’s output will show that the sed package was installed as expected:

. . .
 => [4/4] RUN apk add sed                                                                2.8s
. . .

You can confirm that this package was pulled through Artifactory with the Artifact Repository Browser in the Artifactory dashboard:

  1. Navigate to the Platform tab.
  2. Find Artifactory in the left-hand navigation menu.
  3. Select Artifacts.
  4. Find and expand the menu option for the cg-private Artifactory repository.

There, you will find the sed package listed, along with any other packages you’ve pulled through the remote repository.

Configuring Pull-Through Caches for Chainguard’s Public Repositories

You also have access to the public chainguard and extra-packages repositories. Also, because these repositories are public, they do not require authentication. To set up a pull-through cache for these package repositories on Artifactory, you can follow the same procedure outlined previously for the private APK repository.

You must create two remote repositories within Artifactory — one for each public package repo — by following the same steps as before. Enter the following details for these two remote repositories:

  • Repository Key — This is the name used to identify your remote repository. Again, you can choose whatever names you like here but this guide’s examples use the names cg-chainguard and cg-extras.
  • URL — This must be set to https://virtualapk.cgr.dev/<ORGANIZATION-ID>/chainguard for the chainguard repository and https://virtualapk.cgr.dev/<ORGANIZATION-ID>/chainguard for the extra-packages repository.
    • For both of these URLs, you need to replace the <ORGANIZATION-ID> placeholder with your Chainguard organization’s UID. You can find this by running the chainctl iam organizations list -o table; the UID is the value in your organization’s ID column. Alternatively, you can find it by checking the SettingsGeneral page in the Chainguard Console.

You do not need to set any values for the User Name or Password / Access Token fields, as the public repositories do not require authentication. Keep all the remaining fields set to their default values and click the Create Remote Repository button. This creates the remote repository and returns you to the Repositories page.

After creating both repositories, generate and retrieve a token for each one as you did for the cg-private remote repository:

  1. On the Repositories page, find both remote repositories you just created.
  2. Click the ellipsis () all the way to the right of their respective rows.
  3. Select Set me up.
  4. Click the Generate Token & Create Instructions button.
  5. Copy or take note of the tokens generated for your repositories.

Next, copy the resulting tokens to create a pair of environment variables. For the cg-chainguard repository’s token:

export CG_TOKEN=<cg-chainguard-token>

Then for the cg-extras repo’s token:

export EXTRAS_TOKEN=<cg-extras-token>

Following that, you can use these environment variables, along with a few created earlier in the guide, to create a Dockerfile as you previously did for the cg-private repository:

cat > Dockerfile.repos <<EOF
FROM cgr.dev/chainguard/python:latest-dev
USER root
RUN cp /etc/apk/repositories /etc/apk/repositories.disabled
RUN echo 'https://$ARTIFACTORY_USERNAME:$CG_TOKEN@$ARTIFACTORY_SERVER_NAME.jfrog.io/artifactory/cg-chainguard/' > /etc/apk/repositories
RUN echo 'https://$ARTIFACTORY_USERNAME:$EXTRAS_TOKEN@$ARTIFACTORY_SERVER_NAME.jfrog.io/artifactory/cg-extras/' >> /etc/apk/repositories
RUN apk add c-ares
EOF

Following that, build the image:

docker build -t ar-repos -f Dockerfile.repos .

As this command runs, it installs the c-ares package into the image.

Debugging Pull-Through from Chainguard’s Package Repositories to Artifactory

If you run into issues when trying to pull from Chainguard’s package repositories through Artifactory, you can try checking for these common pitfalls:

  • You may run into issues if your Artifactory username is an email address; specifically, the @ sign can lead to errors. Be sure that you’re using a user profile with a name that only contains letters and numbers. If you must use a profile with an email address for a name, try percent-encoding the @ sign by replacing it with %40.
  • Ensure that all network requirements are met.
  • When configuring a remote Artifactory repository, ensure that the URL field is set correctly.
    • If necessary, ensure that you’ve set the correct UID for your organization in the URL field.
  • It may help to clear the Artifactory cache.
  • It could be that your Artifactory repository was 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 to learn more about Chainguard’s registry. You can also learn more about Chainguard Containers by referring to our documentation, and learn more about working with the Chainguard platform by reviewing our Administration documentation. If you’d like to learn more about JFrog Artifactory, we encourage you to refer to the official Artifactory documentation.

Last updated: 2025-09-24 06:00