---
title: Push a Docker image and deploy it
description: Sign in to the agentlab CLI (alpha), docker push a linux/amd64 image to your organization's registry, and deploy it as a project version. Paid plans only.
url: https://agentlab.cresclab.com/docs/en/deploy/registry
language: en
updated: 2026-10-28
---

# Push a Docker image and deploy it

Sign in to the agentlab CLI (alpha), docker push a linux/amd64 image to your organization's registry, and deploy it as a project version. Paid plans only.

## Before you begin

- A Pro, Team or Business plan. The Free plan has no image registry; deploy [from source](https://agentlab.cresclab.com/docs/en/deploy/source-build.md) or [from a Dockerfile](https://agentlab.cresclab.com/docs/en/deploy/container-app.md) instead.
- A role that can deploy.
- Docker, and Node.js 24 or later for the CLI. The CLI runs on macOS, Linux and Windows, on x64 and arm64.

## 1. Install the CLI

```sh
npm install --global @crescendolab/agentlab-cli@alpha
agentlab --version
```

> [!WARNING] The CLI is an alpha
> Its commands and behavior may change before a stable release. Install it with the `alpha` tag as above.

On Windows, allow the package's install script: it puts `docker-credential-agentlab.exe` next to npm's command shims, where Docker finds it.

## 2. Sign in and set up Docker

```sh
agentlab login
agentlab auth configure-docker
agentlab status
```

`agentlab login` opens your browser: sign in and choose the organization. `agentlab auth configure-docker` adds Agent Lab's credential helper to your Docker configuration, so `docker push` signs in as you; there is no `docker login` step. `agentlab status` shows the account, the organization and when the sign-in expires.

One sign-in is for one organization. To switch, run `agentlab login` again.

## 3. Build and push

An image's path is `registry.agentlab.cresclab.com/<organization id>/<name>:<tag>`. The organization id is a UUID: **Image registry** › **Setup instructions** shows the commands with it filled in.

```sh
docker build --platform linux/amd64 -t registry.agentlab.cresclab.com/<organization id>/orders-api:v1 .
docker push registry.agentlab.cresclab.com/<organization id>/orders-api:v1
```

Build for `linux/amd64`: a push for any other platform is refused. On an Apple silicon Mac, `--platform linux/amd64` is required.

After the push, the image is checked against the [container runtime contract](https://agentlab.cresclab.com/docs/en/deploy/runtime-contract.md), and scanned for vulnerabilities if scanning is on. Its **Check** shows **Checking**, then **Passed**, **Warnings** or **Refused**. A push never changes what is live.

## 4. Deploy the image

1. Open the project's **Deploy** tab. Under **Deploy a new version from**, choose **An image**.
2. Choose the **Repository** and a **Tag or digest**, then **Deploy image**.

Or, from **Image registry**, open the repository and use **Deploy to a project**.

The tag is resolved to a digest when the version is made, so pushing the same tag again later doesn't change that version. With only the production environment, the version goes live on its own once its check passes. With more environments, you choose when on the **Deploy** tab ([Versions](https://agentlab.cresclab.com/docs/en/deploy/versions.md)). A refused image can't be deployed; an image with **Warnings** waits for someone to confirm it.

## Push from CI

In CI, use a robot token instead of the CLI. An owner or admin creates one in **Deploy settings** › **Robot tokens**; it is shown once. It can only push, and it belongs to the organization rather than to the person who created it.

```sh
echo "$AGENTLAB_ROBOT_TOKEN" | docker login registry.agentlab.cresclab.com -u agentlab --password-stdin
docker push registry.agentlab.cresclab.com/<organization id>/orders-api:$GIT_SHA
```

The user name is not checked. Revoke a token in the same place.

## What the image must do

The same rules apply to a pushed image and to one built from a Dockerfile. The [container runtime contract](https://agentlab.cresclab.com/docs/en/deploy/runtime-contract.md) has the full list.

| Rule          | Requirement                                                                                                      |
| ------------- | ---------------------------------------------------------------------------------------------------------------- |
| Platform      | `linux/amd64` only.                                                                                              |
| Start command | A `CMD` or `ENTRYPOINT`.                                                                                         |
| Port          | Serve HTTP on `$PORT`. The port is the project's port setting, else the one port the image `EXPOSE`s, else 8080. |
| User          | A non-root `USER` is recommended. Root, or no `USER`, runs as uid 10001, group 0.                                |
| Filesystem    | Read-only apart from `/tmp`.                                                                                     |
| Size          | Up to 2.5 GiB.                                                                                                   |

## What is kept

- **Five versions per repository.** When a push or a build brings a sixth, the oldest image that nothing uses is removed. An image is in use while it is live, among a project's last 5 versions, or run by a scheduled job. If every image in a repository is in use, the push is refused.
- **Storage per plan:** Pro 50 GB, Team 250 GB, Business by contract.
- **Vulnerability scanning of pushed images** is on Team and Business, off by default: turn on **Scan pushed images** in **Deploy settings**.
- **Projects built from source** keep their images here too, in a repository named after the project.
- **Delete** an image or a whole repository from **Image registry** (administrators only). An image in use can't be deleted.
- **Pulling isn't supported.** The registry takes pushes for deploying; `docker pull` from it is refused.

## CLI commands

| Command                          | What it does                                                                 |
| -------------------------------- | ---------------------------------------------------------------------------- |
| `agentlab login [--org <uuid>]`  | Signs in through your browser. `--org` preselects an organization.           |
| `agentlab auth configure-docker` | Lets Docker use the Agent Lab credential helper for the registry.            |
| `agentlab status [--json]`       | The signed-in account, organization and when the sign-in expires.            |
| `agentlab logout`                | Signs out and removes this computer's saved sign-in and registry credential. |

- The sign-in is kept in your system keychain, or in `~/.config/agentlab/credentials.json` (permissions `0600`) where there is none.
- Owners and admins can turn off **Allow agentlab CLI sign-in** in **Deploy settings**; signed-in CLIs then stop working shortly after. **Signed-in CLIs** lists every sign-in, each with **Revoke sign-in**.
- To remove the CLI: `agentlab logout`, then `npm uninstall --global @crescendolab/agentlab-cli`.

## When a push fails

| What you see                      | Why, and what to do                                                                                                                                   |
| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `unauthorized`                    | Run `agentlab login` again. If you once ran `docker login` for this registry, Docker uses that first: `docker logout registry.agentlab.cresclab.com`. |
| `denied` naming the plan          | The plan has no image registry, or its storage is full. An owner or admin can upgrade in **Settings › Plans and billing**.                            |
| `denied` naming the platform      | The image isn't `linux/amd64`. Build again with `--platform linux/amd64`.                                                                             |
| `denied` naming the version limit | Every image in the repository is in use. Deploy a newer version first, or push to a new repository.                                                   |
| **Refused** after the push        | The image broke a rule above. Its check says which.                                                                                                   |
