---
title: How to Use Vultr Container Registry with Vultr Kubernetes Engine and CI/CD Pipelines
url: https://docs.vultr.com/platform/iam/product-integrations/container-registry-auth/vke-and-cicd
description: Create image pull secrets for VKE and mint short-lived Vultr Container Registry credentials at the start of a CI/CD job.
publish_date: 2026-10-14T13:46:19.683436Z
last_updated: 2026-10-23T20:36:43.652234Z
---

# How to Use Vultr Container Registry with Vultr Kubernetes Engine and CI/CD Pipelines

Vultr Container Registry integrates with IAM, so registry access follows least-privilege policies instead of account-wide API keys. Because Vultr Container Registry mints credentials on demand per IAM policy, the same mechanism applies to the systems that use your images most often. Vultr Kubernetes Engine clusters pull them, and CI/CD pipelines build and push them.

Follow this guide to create an image pull secret for a Vultr Kubernetes Engine (VKE) cluster, keep it up to date, and mint credentials at the start of a CI/CD job using the Vultr API.

> [!NOTE]
> This guide assumes you have already enabled IAM authentication for your registry. See [How to Enable IAM Authentication for Vultr Container Registry](https://docs.vultr.com/platform/iam/product-integrations/container-registry/enable-iam-auth) for the setup steps.

## Use the Registry with Vultr Kubernetes Engine

To pull private images in a VKE cluster, create an image pull secret from minted credentials, then reference it in your workload. A cluster only pulls images, so use an identity with `container.registry.Pull` and mint read-only credentials.

### Create the Image Pull Secret

Mint read-only credentials scoped to the registry and store them as a Kubernetes secret.

1. Set your kubeconfig so that `kubectl` targets the cluster, then send a `POST` request to the Kubernetes-specific credential endpoint and pipe the response to `kubectl`. Replace `REGISTRY_ID` with your registry's id.

    ```console
    $ curl "https://api.vultr.com/v2/container-registry/docker-credentials/kubernetes" \
        -X POST \
        -H "Authorization: Bearer ${VULTR_API_KEY}" \
        -H "Content-Type: application/json" \
        -d '{
            "registry": "REGISTRY_ID",
            "expiry_seconds": 2592000
        }' | kubectl apply -f -
    ```

    The endpoint returns raw YAML that `kubectl apply` accepts as input. It creates a secret named `vultr-cr-credentials`, valid for the `expiry_seconds` you set. If your pipeline expects the YAML base64-encoded, add the query parameter `?base64_encode=true` to the URL.

1. Verify that the secret exists.

    ```console
    $ kubectl get secret vultr-cr-credentials
    ```

    > [!NOTE]
    > A Kubernetes secret belongs to a namespace. Apply it in the same namespace as the workloads that use it.

### Reference the Secret in Your Workload

Add the secret to `imagePullSecrets` in your pod template. The following example is a patch for a Deployment.

```yaml
spec:
  template:
    spec:
      imagePullSecrets:
        - name: vultr-cr-credentials
```

Kubernetes then uses the credentials to pull images from your registry. The existing per-registry Kubernetes YAML generation flow, described in Generate Docker Config, also remains available.

## Use the Registry in CI/CD Pipelines

Use a service user for each pipeline. Give it a narrow policy, such as push and pull on a single build registry, and mint short-lived credentials at the start of each job. The job logs in, builds and pushes, and the credentials expire shortly afterward.

### Create the Pipeline Identity

Give the pipeline its own identity so it can mint credentials independently of any individual user.

1. Create a service user for the pipeline in your IAM organization. See [Identity and Access Management](https://docs.vultr.com/platform/iam) for details.

1. Attach a policy that grants `GetCredentials` on `*` and `Pull` and `Push` on the build registry. Replace `REGISTRY_ID` with your registry's id.

    ```json
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": ["container.registry.GetCredentials"],
          "Resource": ["*"]
        },
        {
          "Effect": "Allow",
          "Action": ["container.registry.Pull", "container.registry.Push"],
          "Resource": ["registry:REGISTRY_ID"]
        }
      ]
    }
    ```

1. Store the service user's API key in your pipeline's secret store as `VULTR_API_KEY`.

### Mint Credentials at the Start of a Job

Add the following steps to your pipeline runner before any step that uses the registry.

1. Mint short-lived push credentials for the build registry. Replace `REGISTRY_ID` with your registry's id.

    ```console
    $ curl "https://api.vultr.com/v2/container-registry/docker-credentials" \
        -X POST \
        -H "Authorization: Bearer ${VULTR_API_KEY}" \
        -H "Content-Type: application/json" \
        -d '{
            "registry": "REGISTRY_ID",
            "expiry_seconds": 3600,
            "read_write": true
        }' > creds.json
    ```

1. Extract the `auth` value for your registry host from `creds.json`. Replace `REGISTRY_HOST` with your registry host.

    ```console
    $ AUTH=$(jq -r '.auths["REGISTRY_HOST"].auth' creds.json)
    ```

1. Decode the value.

    ```console
    $ LOGIN=$(echo "$AUTH" | base64 -d)
    ```

1. Log in to the registry. Replace `REGISTRY_HOST` with the same registry host. Passing the password over `stdin` keeps it out of your shell history.

    ```console
    $ echo "${LOGIN#*:}" | docker login REGISTRY_HOST -u "${LOGIN%%:*}" --password-stdin
    ```

1. Remove the credentials file.

    ```console
    $ rm creds.json
    ```

    A successful login returns `Login Succeeded`.
