> ## 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.

# Push Images to Registry

> Build and push container images to Control Plane's private registry.

Push container images to your organization's private registry on Control Plane. Use Docker, the CLI, or any Docker-compatible client.

## When to use this

<CardGroup cols={2}>
  <Card title="CI/CD pipelines" icon="code">
    Build and push images in automated pipelines
  </Card>

  <Card title="Local development" icon="laptop">
    Push locally-built images for testing
  </Card>

  <Card title="Private registry" icon="key">
    Store images in your org's secure registry
  </Card>

  <Card title="No Dockerfile" icon="wand-magic-sparkles">
    Build automatically with buildpacks
  </Card>
</CardGroup>

## Prerequisites

<AccordionGroup>
  <Accordion title="CLI installed">
    Install the Control Plane CLI. See [Installation](/cli-reference/installation).
  </Accordion>

  <Accordion title="Docker installed">
    Install [Docker](https://www.docker.com). The Buildx plugin is recommended (used by default when available) but no longer required for single-platform builds.
  </Accordion>

  <Accordion title="Required permissions">
    You need push permission on images. See [Image Permissions](/reference/image#minimum-policy).
  </Accordion>

  <Accordion title="Docker Buildx (recommended)">
    As of CLI v3.7.2, `cpln image build` uses `docker buildx build`. As of CLI v3.9.0, it falls back to legacy `docker build` when Buildx is unavailable, so Buildx is optional for single-platform builds. Multi-platform builds (comma-separated `--platform` values) still require Buildx.

    Verify Buildx is available:

    ```bash theme={null}
    docker buildx version
    ```

    If not installed, add the plugin:

    ```bash theme={null}
    BUILDX_VERSION=v0.29.1
    curl -sSL "https://github.com/docker/buildx/releases/download/${BUILDX_VERSION}/buildx-${BUILDX_VERSION}.linux-amd64" \
      | install -m 0755 -D /dev/stdin ~/.docker/cli-plugins/docker-buildx
    ```
  </Accordion>
</AccordionGroup>

## Build and push

<Tabs>
  <Tab title="Using the CLI (Recommended)">
    **Best for:** Local development, CI/CD pipelines, buildpack builds

    * Authenticates to your org's private registry automatically
    * Simple naming (`--name my-app:v1`)
    * Supports Dockerfile or Buildpacks

    ### With a Dockerfile

    The Dockerfile is automatically detected (defaults to `./Dockerfile`):

    ```bash theme={null}
    cpln image build --name my-app:v1 --push
    ```

    Or specify a different path:

    ```bash theme={null}
    cpln image build --dockerfile ./path/to/Dockerfile --name my-app:v1 --push
    ```

    <Tip>
      Learn more about working with images: [CLI images guide](/cli-reference/get-started/images) | [Command reference](/cli-reference/commands/image)
    </Tip>

    ### With Buildpacks

    Build automatically without a Dockerfile:

    ```bash theme={null}
    cpln image build --name my-app:v1 --push
    ```

    Buildpacks detect your language and create an optimized image. See [Buildpacks conventions](/cli-reference/get-started/images#buildpacks-conventions) for language-specific requirements.
  </Tab>

  <Tab title="Using Docker directly">
    **Best for:** Existing Docker workflows, custom build processes, external CI/CD systems

    * Requires manual authentication
    * Must use full registry path: `ORG.registry.cpln.io/IMAGE:TAG`

    ### Image name format

    When using Docker directly, images must use this format:

    ```
    ORG_NAME.registry.cpln.io/IMAGE_NAME:TAG
    ```

    Examples:

    * `my-org.registry.cpln.io/api:v1.0.0`
    * `my-org.registry.cpln.io/frontend:latest`
    * `my-org.registry.cpln.io/worker:abc123`

    ### Push steps

    <Steps>
      <Step title="Authenticate Docker">
        Configure Docker to authenticate with your org's registry:

        ```bash theme={null}
        cpln image docker-login
        ```

        <Tip>
          This uses your default CLI profile. Set `CPLN_PROFILE` to use a different profile.
        </Tip>
      </Step>

      <Step title="Build the image">
        Build with the correct tag format:

        ```bash theme={null}
        docker buildx build --platform=linux/amd64 \
          -t my-org.registry.cpln.io/my-app:v1 .
        ```

        <Warning>
          Always target `linux/amd64` to ensure compatibility with Control Plane.
        </Warning>
      </Step>

      <Step title="Tag an existing image (optional)">
        If you have an existing image, tag it for your registry:

        ```bash theme={null}
        docker tag my-app:v1 my-org.registry.cpln.io/my-app:v1
        ```
      </Step>

      <Step title="Push to registry">
        ```bash theme={null}
        docker push my-org.registry.cpln.io/my-app:v1
        ```
      </Step>
    </Steps>

    ### CI/CD authentication

    For CI/CD pipelines without the CLI, authenticate with a service account:

    ```bash theme={null}
    echo $SERVICE_ACCOUNT_KEY | docker login my-org.registry.cpln.io -u '<token>' --password-stdin
    ```

    | Parameter | Value                       |
    | --------- | --------------------------- |
    | Registry  | `ORG_NAME.registry.cpln.io` |
    | Username  | `<token>` (literal string)  |
    | Password  | Service account key         |

    <Warning>
      Store the service account key securely. If compromised, delete and regenerate it.
    </Warning>

    See [Create a Service Account](/guides/create-service-account) for key generation.
  </Tab>
</Tabs>

## Reference images in workloads

Once pushed, reference your images in workloads using the Control Plane image link format.

<Warning>
  **Important:** Do not use the Docker registry path (`org.registry.cpln.io/...`) in workload configurations. Always use the Control Plane image link format shown below.
</Warning>

**Shorthand format (recommended):**

```text theme={null}
//image/IMAGE_NAME:TAG
```

**Full format:**

```text theme={null}
/org/ORG_NAME/image/IMAGE_NAME:TAG
```

**Example workload configuration:**

```yaml theme={null}
containers:
  - name: my-container
    image: //image/my-app:v1
```

Or with the full path:

```yaml theme={null}
containers:
  - name: my-container
    image: /org/my-org/image/my-app:v1
```

<Tip>
  In the console, press `Ctrl+I` when configuring a workload to browse available images.
</Tip>

## Common workflows

### Build and deploy

```bash theme={null}
# Build and push (Authenticates automatically)
cpln image build --name my-app:v1.2.3 --push

# Update workload
cpln workload update my-app --set spec.containers<container-name>.image=//image/my-app:v1.2.3
```

### CI/CD pipeline

```bash theme={null}
# Build and push (Authenticates automatically)
cpln image build --name my-app:$CI_COMMIT_SHA --push

# Deploy (has the new image defined in the workload manifest container)
cpln apply --file workload.yaml
```

## Troubleshooting

For common issues with building and pushing images, see [Images Troubleshooting](/cli-reference/get-started/images#troubleshooting).

## Next steps

<CardGroup cols={2}>
  <Card title="Pull Images" href="/guides/pull-image" icon="download">
    Configure workloads to pull images
  </Card>

  <Card title="Copy Images" href="/guides/copy-image" icon="copy">
    Copy images between organizations
  </Card>

  <Card title="Create a Workload" href="/guides/create-workload" icon="cube">
    Deploy your pushed images
  </Card>

  <Card title="Image Reference" href="/reference/image" icon="book">
    Image configuration details
  </Card>
</CardGroup>
