# How to use Vercel Container Registry

**Author:** Ben Sabic

---

Getting a container image from your laptop to a running function usually means setting up a separate registry, configuring credentials, and configuring your build pipeline to push to it. Vercel Container Registry (VCR) removes that step by giving every Vercel project a built-in, OCI-compatible registry at `vcr.vercel.com`. You push images with the same `docker` tooling you already use. Vercel Functions and Vercel Sandbox pull them directly, and VCR optimizes images automatically for Fluid compute.

In this guide, you'll learn how to authenticate Docker with Vercel Container Registry, build and push an OCI image to your project's registry, pull it for local verification or CI, and reference it from a Vercel Function or Vercel Sandbox, all within VCR's size, format, and plan limits.

## Prerequisites

Before you begin, make sure you have:

- A [Vercel account](https://vercel.com/signup) with access to the project you want to push to
  
- [Docker](https://docs.docker.com/get-docker/) installed and running locally, and optionally [Docker Buildx](https://docs.docker.com/buildx/working-with-buildx/) (multi-platform)
  
- The [Vercel CLI](https://vercel.com/docs/cli) installed and authenticated with `vercel login`
  
- A local project linked to your Vercel project with `vercel link`
  

## How it works

Every Vercel project has its own namespace in VCR. A full image reference has four parts: the registry host, your team slug, your project slug, and the repository name with a tag or digest.

`vcr.vercel.com/team-slug/project-slug/my-repository:latest`

VCR speaks the Docker Registry HTTP API v2 and stores images in OCI format, so `docker login`, `docker push`, `docker pull`, and `docker tag` work without extra tooling. When you push an image, VCR builds an optimized snapshot in the background so it boots faster inside Vercel Functions and Vercel Sandbox on Fluid compute.

## Steps

### 1\. Link your project and pull environment variables

From the root of the project you want to push images for, link the local directory to your Vercel project and download its environment variables:

`vercel link vercel env pull .env.local source .env.local`

`vercel env pull` writes `VERCEL_OIDC_TOKEN` into `.env.local`, which you'll use as the Docker password. The token is scoped to the linked project and expires after 12 hours, so refresh it with `vercel env pull` before the 12-hour window closes.

### 2\. Authenticate Docker with VCR

Log Docker in to `vcr.vercel.com` using the OIDC token as the password and `oidc` as the username:

`printf '%s' "$VERCEL_OIDC_TOKEN" | docker login vcr.vercel.com \ --username oidc \ --password-stdin`

Docker responds with `Login Succeeded` when the credentials are accepted.

If OIDC isn't available in your environment (e.g., in a CI system that doesn't run `vercel env pull`), create a token on the [Account Tokens page](https://vercel.com/account/tokens) and log in with your team ID as the username:

`printf '%s' "$VERCEL_TOKEN" | docker login vcr.vercel.com \ --username "$VERCEL_TEAM_ID" \ --password-stdin`

### 3\. Build and tag the image locally

Tag the image with the full VCR path so `docker push` knows where to send it. Replace `team-slug` and `project-slug` with the values for your linked project.

`docker build -t vcr.vercel.com/team-slug/project-slug/my-repository:latest`

If the repository doesn't exist yet, VCR creates it the first time you push, provided you have access to the project.

### 4\. Push the image to VCR

To push the image, use `docker push` with the tag you built:

`docker push vcr.vercel.com/team-slug/project-slug/my-repository:latest`

For production images, build with Buildx and zstd compression. This produces smaller layers and faster snapshot boots on Fluid compute, and lets you build for both `linux/amd64` and `linux/arm64` in one step:

`docker buildx build \ --platform linux/amd64,linux/arm64 \ --output "type=image,name=vcr.vercel.com/team-slug/project-slug/my-repository:latest,push=true,oci-mediatypes=true,compression=zstd,compression-level=3,force-compression=true"`

### 5\. Pull the image for verification

To confirm the push landed, pull the image back to your machine or into a CI job using the same full path:

`docker pull vcr.vercel.com/team-slug/project-slug/my-repository:latest`

You can also browse tags and digests from the Images tab in your project dashboard.

### 6\. Reference the image from Vercel Functions

To run the image as a Vercel Function, add a `Dockerfile.vercel` (or `Containerfile.vercel`) at the root of your project. Vercel detects it during the build, pushes the image to VCR, and routes traffic to the resulting function.

`FROM node:26-alpine RUN npm i -g srvx WORKDIR /app COPY server.ts . # srvx listens on $PORT by default CMD ["srvx", "--prod"]` Deploy with `vercel deploy` or by pushing to a connected Git branch. Container-based functions serve HTTP on port `80` by default; you can override this by setting the `PORT` environment variable in your project settings. They follow the same Active CPU pricing and limits as any other Vercel Function. Note that Secure Compute and Static IPs are not yet supported with custom container images. ### 7\. Reference the image from Vercel Sandbox Custom images for Vercel Sandbox are available in public beta. To boot a sandbox from a custom VCR image, pass the repository and tag to `Sandbox.create()`: `import { Sandbox } from "@vercel/sandbox"; const sandbox = await Sandbox.create({ image: "my-repository:latest", });` The sandbox boots from your image's filesystem rather than the built-in runtime, so the system libraries and toolchains specified in your Dockerfile are already in place. Note that Sandbox requires a `linux/amd64` manifest and only boots the image after VCR finishes preparing an optimized build. If `Sandbox.create()` returns `image_not_ready`, retry once preparation completes. You can check the readiness state on the repository details page. Sandbox also does not run your image's `ENTRYPOINT` or `CMD`; start processes with `sandbox.runCommand()` after creation. If your Dockerfile defines a `WORKDIR`, commands start there; otherwise they start from `/`. ## Limits and best practices Keep these limits in mind when planning your images. ### Size limits | Limit                 | Maximum | Notes                                                  | | --------------------- | ------- | ------------------------------------------------------ | | Compressed layer size | 500 MB  | Per layer                                              | | Total image size      | 15 GB   | Calculated from compressed layers plus the config blob | | Manifest body         | 4 MB    | —                                                      | | Image config blob     | 1 MB    | —                                                      | ### Compatibility - Compression: VCR accepts gzip or zstd compression only. Uncompressed OCI layers are rejected.    - Formats: OCI image manifests, OCI image indexes, Docker schema 2 image manifests, and Docker manifest lists    - Single-platform manifests must declare `os` and `architecture` in the image config    - Vercel Sandbox requires a `linux/amd64` manifest to boot the image    ### Plan limits and pricing | Limit                    | Hobby | Pro    | Enterprise | | ------------------------ | ----- | ------ | ---------- | | Repositories per project | 10    | 1,000  | 5,000      | | Images per repository    | 50    | 10,000 | 50,000     | | Tags per repository      | 1,000 | 10,000 | 50,000     | Storage costs $0.10 per GB across all plans. See [limits and pricing](https://vercel.com/docs/container-registry/limits-and-pricing) for current details.

Additional practices to keep in mind:

- Build with Docker Buildx and zstd compression for faster boots on Fluid compute
  
- Use immutable tags (like a commit SHA) for production images, and reserve `latest` for local iteration
  
- Push from your Vercel build environment when possible; it's authenticated for the current project automatically
  

## Resources and next steps

- [Vercel Container Registry documentation](https://vercel.com/docs/container-registry)
  
- [Container Registry limits and pricing](https://vercel.com/docs/container-registry/limits-and-pricing)
  
- [Running container images on Vercel Functions](https://vercel.com/docs/functions/container-images)
  
- [Using custom images with Vercel Sandbox](https://vercel.com/docs/sandbox/concepts/images)
  
- [Introducing VCR: Vercel Container Registry (changelog)](https://vercel.com/changelog/introducing-vcr-vercel-container-registry)

---

[View full KB sitemap](/kb/sitemap.md)
