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

# Image

> Container image management including private registry details, image reference formats, tagging, and support for internal and external image sources.

## Overview

An image is a lightweight, standalone, executable package that includes everything needed to run an application: code, runtime, system tools, system libraries, and settings. Control Plane uses container images to deploy and run your applications as [workloads](/concepts/workload).

Control Plane provides each organization with a private image registry at `your-org.registry.cpln.io`. You can also use external registries like Docker Hub, Google Container Registry, or Amazon ECR.

The [CLI](/cli-reference/get-started/images) provides commands to build and push your application to your private image registry.

## Private Registry

Each organization has a dedicated private registry hosted by Control Plane.

**Registry URL format:**

```text theme={null}
ORG_NAME.registry.cpln.io/IMAGE_NAME:TAG
```

**Benefits:**

* No [pull secrets](/reference/secret) required when referencing images in workloads
* Lower latency when pulling images (images are cached at each location where your workload is deployed)
* Built-in access control through Control Plane policies
* Automatic authentication when using the CLI

## Image Reference Formats

When configuring a workload's container image, you can reference images from different sources:

| Format                           | Description                             | Example                                               |
| -------------------------------- | --------------------------------------- | ----------------------------------------------------- |
| `//image/IMAGE:TAG`              | Image in your org's private registry    | `//image/my-app:v1`                                   |
| `ORG.registry.cpln.io/IMAGE:TAG` | Explicit reference to an org's registry | `my-org.registry.cpln.io/my-app:v1`                   |
| `IMAGE:TAG`                      | Public image from Docker Hub            | `nginx:latest`                                        |
| `gcr.io/PROJECT/IMAGE:TAG`       | Google Container Registry               | `gcr.io/my-project/my-app:v1`                         |
| `ECR_URL/IMAGE:TAG`              | Amazon Elastic Container Registry       | `123456789.dkr.ecr.us-east-1.amazonaws.com/my-app:v1` |

<Tip>
  Use `//image/IMAGE:TAG` for images in your org's private registry. This short format is resolved automatically and doesn't require the full registry URL.
</Tip>

## Internal vs External Images

| Aspect            | Internal (Private Registry)                    | External (Docker Hub, GCR, ECR, etc.)      |
| ----------------- | ---------------------------------------------- | ------------------------------------------ |
| Authentication    | Automatic via Control Plane                    | Requires [pull secrets](/reference/secret) |
| Latency           | Optimized (cached at each deployment location) | Depends on external registry location      |
| Access control    | Control Plane policies                         | External registry permissions              |
| Build integration | `cpln image build --push`                      | Standard `docker push`                     |
| Best for          | Production workloads, proprietary code         | Public images, shared base images          |

## Building Images

Control Plane supports two methods for building container images:

### With a Dockerfile

The traditional approach using a Dockerfile to define your image. Use this when you need full control over the build process or have complex build requirements.

### With Buildpacks

[Cloud Native Buildpacks](https://buildpacks.io) automatically detect your application language and create an optimized container image without a Dockerfile. Buildpacks are ideal for standard application frameworks and reduce the need to maintain Dockerfiles.

<Info>
  For detailed language-specific requirements and conventions, see the [Buildpacks Guide](/guides/buildpacks).
</Info>

## Image Lifecycle

1. **Build**: Create the image locally using `cpln image build` (with Dockerfile or buildpacks)
2. **Push**: Upload to your org's private registry with the `--push` flag or `docker push`
3. **Reference**: Configure your workload to use the image via `//image/IMAGE:TAG`
4. **Deploy**: Control Plane pulls and runs the image across your configured locations

## Getting Started with the CLI

For practical examples on building, pushing, and managing images, see [Images](/cli-reference/get-started/images) in the CLI Reference.

<Note>
  `cpln image build` prefers `docker buildx build` (used by default since CLI `v3.7.2`) and falls back to legacy `docker build` when Buildx is unavailable (fallback added in CLI `v3.9.0`). Multi-platform builds (comma-separated `--platform` values) still require Buildx and will fail without it. To install the plugin, follow Docker's [Buildx installation guide](https://docs.docker.com/build/install-buildx/) or see the [Push an Image guide](/guides/push-image) (especially on CI runners).
</Note>

## Push an Image

Refer to the [Push an Image](/guides/push-image) guide for additional details.

## Pull an Image

Refer to the [Pull an Image](/guides/pull-image) guide for additional details.

## Copy an Image

Refer to the [Copy an Image](/guides/copy-image) guide for additional details.

## Update a Workload Image

To update the image used by a workload's container:

```bash theme={null}
cpln workload update WORKLOAD_NAME --set spec.containers.CONTAINER_NAME.image=//image/IMAGE:TAG --gvc GVC_NAME --org ORG_NAME
```

<Note>
  Use the convention `//image/IMAGE:TAG` to reference an image residing within the current org's private registry.
</Note>

## Dynamic Tags

Enable `supportDynamicTags` on a workload to automatically redeploy when an image tag's underlying digest changes. This is useful for:

* Mutable tags like `latest` or `dev`
* CI/CD pipelines that update the same tag
* Automatic rollout of security patches to base images

When enabled, Control Plane periodically checks if the image digest has changed and triggers a redeployment if it has.

<Warning>
  Using mutable tags in production is generally discouraged. Prefer immutable tags (e.g., `v1.2.3`, commit SHAs) for predictable deployments.
</Warning>

## Image Tags and Digests

**Tags** are human-readable labels pointing to a specific image version:

```text theme={null}
my-app:v1.0.0
my-app:latest
my-app:abc123  # commit SHA
```

**Digests** are immutable SHA256 hashes that uniquely identify an image:

```text theme={null}
my-app@sha256:3fe719...
```

<Tip>
  For production deployments, use specific version tags or digests rather than `latest` to ensure reproducible deployments.
</Tip>

## Permissions

The permissions below are used to define [policies](/reference/policy) together with one or more of the four [principal types](/concepts/access-control):

| Permission | Description                                              | Implies                                  |
| :--------- | :------------------------------------------------------- | :--------------------------------------- |
| create     | Create new image. You can push if you can create images. | pull                                     |
| delete     | Delete                                                   |                                          |
| edit       | Modify existing image (only tags can be changed)         | view                                     |
| manage     | Full access                                              | create, delete, edit, manage, pull, view |
| pull       | Image can be pulled                                      | view                                     |
| view       | Read-only access                                         |                                          |

## Minimum Policy

### Push

At a minimum, the `create` permission must be bound to the principal pushing an image to an org's private registry.

Using the console UI, follow these steps to create a least privileged [policy](/reference/policy) which will allow a principal to push an image:

1. Click `Policies` in the left menu bar and click the `New` button at the top of the form.
2. Enter a policy name, select `image` from the Target Kind pulldown, and enable the `Target All Images` button. Click the `Next` button.
3. Click `Add Binding`.
4. Select the `create` permission. Select the principal type that will be pushing the image from the top menu bar and select the principal. Click `Add`.
5. Click `Create`.

The policy is now active and the principal has the ability to push images to the org's private registry.

### Pull

At a minimum, the `pull` permission must be bound to a principal pulling an image from an org's private registry.

Unless the [policy](/reference/policy) targets all images, a query must be created with the image names (without the tag) that the principal is allowed to pull. That query uses the `property` parameter and can only be created/updated using [cpln apply](/guides/cpln-apply) or the CLI's [cpln policy](/cli-reference/commands/policy) command.

Below is a sample JSON manifest used as input to `cpln apply`.

**Notice that the `property` parameter is equal to `repository`.**

Update the `POLICY_NAME`, `ORG_NAME`, `USER_EMAIL`, `SERVICE_ACCOUNT_NAME`, and `IMAGE_NAME` tokens.

The `principalLinks` can refer to a user or service account.

```json JSON theme={null}
{
  "kind": "policy",
  "name": "POLICY_NAME",
  "description": "",
  "tags": {},
  "origin": "default",
  "bindings": [
    {
      "permissions": ["pull"],
      "principalLinks": ["/org/ORG_NAME/user/USER_EMAIL", "/org/ORG_NAME/serviceaccount/SERVICE_ACCOUNT_NAME"]
    }
  ],
  "targetKind": "image",
  "targetLinks": [],
  "targetQuery": {
    "kind": "image",
    "fetch": "items",
    "spec": {
      "match": "all",
      "terms": [
        {
          "op": "=",
          "property": "repository",
          "value": "IMAGE_NAME"
        }
      ]
    }
  }
}
```

Once the policy is active, the principal will have the ability to pull images using any Docker compatible tool (e.g., `docker pull ...`).

## Access Report

Displays the permissions granted to principals for the image. Available in the console UI or via the CLI with `cpln image access-report IMAGE:TAG`.

## Learn More

<CardGroup cols={2}>
  <Card title="Push Images" href="/guides/push-image" icon="upload">
    Build and push images to your private registry
  </Card>

  <Card title="Pull Images" href="/guides/pull-image" icon="download">
    Configure workloads to pull from private registries
  </Card>

  <Card title="Buildpacks Guide" href="/guides/buildpacks" icon="cubes">
    Language-specific conventions for building without Dockerfiles
  </Card>

  <Card title="CLI Image Commands" href="/cli-reference/commands/image" icon="terminal">
    Full CLI command reference for images
  </Card>
</CardGroup>
