Vercel supports Docker across your whole workflow. You can deploy an application packaged as an OCI (Open Container Initiative) container image as an autoscaling Vercel Function on Fluid compute, store images in Vercel Container Registry (VCR), run containers inside Vercel Sandbox for testing, and use Docker locally to keep builds reproducible. Each path suits a different stage of building and shipping.
This guide will teach you how to run Docker on Vercel across every stage of building and shipping, from local development through to production.
Vercel works with Docker in a few distinct ways, depending on what you're trying to do:
| Where Docker fits | What it's for |
|---|---|
| Vercel Functions | Ship a containerized app with autoscaling and Active CPU pricing |
| Vercel Container Registry | Store, push, and pull OCI images for functions and sandboxes |
| Vercel Sandbox | Test images and run containerized dependencies in isolation |
| Local Development | Reproduce builds and test container images before deploying |
The main way to run Docker on Vercel is to deploy a container image as a Vercel Function. Add a Dockerfile.vercel (or Containerfile.vercel) to your project root, and Vercel builds the image, stores it in VCR, and serves it from a Function that scales automatically with traffic. You're billed only for the CPU your code actively uses, and the Function scales to zero when idle.
Reach for this when framework detection can't cover your app:
- It depends on a system library such as FFmpeg or Chromium
- It uses a framework Vercel doesn't auto-detect yet
- It needs to run exactly as it does elsewhere
Vercel detects the Dockerfile.vercel at your project root and adds a rewrite that routes all traffic to the resulting image. Here's a minimal dynamic server using Node.js and the srvx server:
Static servers work the same way. A Dockerfile.vercel that starts FROM nginx:alpine and copies your files into /usr/share/nginx/html serves them as static content. Deploy either kind by running vercel deploy or by pushing to a connected Git repository.
To deploy more than one application in a single project, define each one as a service and route traffic between them with rewrites in vercel.json. Set each service's entrypoint to its Dockerfile path, relative to the service's root:
| Behavior | What to expect |
|---|---|
| Port Resolution | Containers serve HTTP traffic on port 80 by default. Override it with the PORT environment variable in project settings. |
| Scale-in | Functions that receive no traffic for five minutes in production or 30 seconds in preview scale down. On scale-down, the container receives SIGTERM with a 30-second grace period before termination. |
| Observability | Vercel broadcasts stdout and stderr logs to all inflight requests on the instance, and Vercel Observability metrics work like any other function. |
| Pricing and Limits | Container image functions follow the same Active CPU pricing model and limits as every other Vercel Function. |
Vercel Container Registry (VCR) is a project-scoped registry for OCI images, hosted at vcr.vercel.com. It supports the Docker Registry HTTP API v2, so docker push, docker pull, and docker tag work without new tooling. A full image reference includes the registry host, team slug, project slug, repository name, and tag:
Vercel provides VERCEL_OIDC_TOKEN automatically in deployments. For local use, run vercel link and vercel env pull to get the token, then authenticate and push:
Vercel recommends building with Docker Buildx and zstd compression for images you push to VCR. Once an image is in VCR, both Vercel Functions and Vercel Sandbox can use it. For authentication options, compression flags, and limits, see the Vercel Container Registry documentation.
Vercel Sandbox gives you an isolated Linux environment for safely running untrusted or user-generated code, and it works with Docker in two ways:
- You can install and run the Docker engine inside a sandbox
- You can boot a sandbox directly from a custom image in VCR
Sandboxes can install and run Docker, allowing you to build images and run containers without touching your host system. Each sandbox is a Firecracker microVM with its own kernel and filesystem, and it runs with sudo access, which is what lets you start the Docker daemon inside it. This is useful for running containerized services like Redis or Postgres as test dependencies, validating an image before you deploy it, or previewing an app served from a container.
Install Docker, start the daemon, then run a container:
Starting a container runtime needs system-level privileges, so run these commands with sudo. With persistent sandboxes, the Docker installation and any pulled images carry over between sessions, so you skip setup on the next run.
One behavior to watch: a container you run inside a sandbox has its own filesystem and trust store, so it doesn't inherit the sandbox's proxy CA certificate. The sandbox host mounts that certificate at /etc/pki/ca-trust/source/anchors/vercel-proxy-ca.pem and trusts it automatically, but a container started inside the sandbox can't see it. As a result, HTTPS requests from inside the container fail TLS verification when the sandbox firewall terminates them.
To fix this, mount the certificate into the container and add it to the container's own trust store at build or run time:
The exact location and trust-update command depend on the base image: use update-ca-certificates on Debian or Ubuntu, and update-ca-trust on Amazon Linux, Fedora, or RHEL. If your app reads a CA bundle from an environment variable instead of the system trust store, point that variable (such as NODE_EXTRA_CA_CERTS) at the mounted certificate path inside the container.
To define the sandbox environment itself with Docker, push your image to VCR and boot the sandbox from it instead of installing packages at runtime:
The sandbox boots with your image's packages and tools already in place, rather than a built-in runtime. See sandbox images to learn how to build and push a custom image.
Docker also fits into local development. To develop and test a container image before deploying, run vercel dev, which needs the docker CLI and a running Docker daemon on your machine. Even for zero-configuration frameworks you deploy without a container, a Dockerfile can pin dependencies and give you a consistent build environment across machines. The Next.js repository includes a Dockerfile example for this workflow. To verify a Vercel build locally without pushing code, run vercel build, then run vercel deploy --prebuilt to upload the output from .vercel/output without sending source code.
- See the Container Images documentation for configuration details, including Services and
rewrites. - Learn how to store, push, and pull images in Vercel Container Registry.
- Explore Vercel Sandbox to build and test containers in an isolated environment.
- Try the Next.js Dockerfile example for local development.
- Learn more about Vercel Services to run frontends and backends in one project.