No. Vercel has no Docker Compose deployment target, so you can't point a deployment at a docker-compose.yml. What Vercel runs is single container images as Vercel Functions, and the multi-container shape a compose file describes maps to services declared in vercel.json.
This article maps each Compose concept to its Vercel equivalent, translates a small compose file into services, and covers what doesn't translate at all.
Copy link to headingHow does Vercel run containers instead?
Vercel runs OCI container images as Vercel Functions. A Dockerfile.vercel (or Containerfile.vercel) at the project root is auto-detected, built during the build step, pushed to Vercel Container Registry, and served from a function that scales automatically. The container must open an HTTP server: the default port is 80, and you can override it with the PORT environment variable in project settings. Instances scale down after 5 idle minutes in production (30 seconds in preview) and receive SIGTERM with a 30-second grace period. Billing uses Active CPU pricing, the same model as other Vercel Functions. The guide on Docker deployments on Vercel walks through those mechanics end to end, so this page won't repeat the walkthrough.
That covers one container. For the multi-container part, Vercel has services, currently in public beta: multiple backends and frontends deploy within a single Vercel project, declared under a services key in vercel.json. Each service has a root. A service is internal by default, and a top-level rewrite whose destination is { "service": "<name>" } is what exposes it to the internet. To build a service as a container image, set the service's runtime to container; with container images, entrypoint points at the Dockerfile path relative to the service's root.
Copy link to headingHow do Compose concepts map to Vercel?
Each row's left side is a line you'd find in a docker-compose.yml; the right side is where that job lands on Vercel.
Copy link to headingTranslate a compose file into services
Take a common compose shape: a web frontend, an API it calls, and a Postgres database with a named volume.
services: web: build: ./web ports: - "3000:3000" environment: API_URL: http://api:4000 api: build: ./api environment: DATABASE_URL: postgres://db:5432/app depends_on: - db db: image: postgres:16 volumes: - dbdata:/var/lib/postgresql/datavolumes: dbdata:Two of the three services translate. web and api are HTTP services built from Dockerfiles, so each becomes a service in vercel.json with a Dockerfile.vercel in its root:
{ "services": { "web": { "root": "web/", "entrypoint": "Dockerfile.vercel" }, "api": { "root": "api/", "entrypoint": "Dockerfile.vercel" } }, "rewrites": [ { "source": "/api/(.*)", "destination": { "service": "api" } }, { "source": "/(.*)", "destination": { "service": "web" } } ]}Here is where each remaining compose line went:
The
ports:mappings became the tworewrites. There is one public surface: requests under/api/route toapi, everything else routes toweb, and each container serves HTTP onPORT(default 80) instead of publishing its own host port.API_URL: http://api:4000relied on Compose's service DNS. On Vercel,webdeclares a binding toapi, and Vercel injects the target service's URL as an environment variable, so the call never crosses the public internet. If you remove the/api/(.*)rewrite,apistays unreachable from the internet and onlywebcan call it.dbdoesn't deploy at all. Containers on Vercel are stateless, so Postgres and itsdbdatavolume move to a managed backing service, such as a database from the Vercel Marketplace, andDATABASE_URLbecomes a project environment variable.depends_on: dbhas nothing to point at anymore. There is no startup order to manage: all services in a project share the same deployment and deploy atomically.
For local development, vercel dev runs all services together with binding environment variables injected, so calls between services work the same locally as in production. Running container images locally requires the docker CLI and a running Docker daemon.
Copy link to headingWhat doesn't translate
The compose file itself. There is no compose deployment target and no converter tool that turns a
docker-compose.ymlintovercel.json. The translation is manual, which is why the table above exists.Stateful services. Postgres, Redis, MinIO, and similar containers don't move into Vercel containers; they map to managed backing services. In-container databases are the part of a compose stack that gets re-homed, not translated.
Volumes. Named volumes and bind mounts have no equivalent: files go to blob storage, data goes to managed databases.
Non-HTTP services. Workers and one-shot init containers don't fit the request-driven model, since every container function must serve HTTP. Scheduled work maps to cron jobs; an always-on worker belongs on a platform built for long-lived processes.
Nothing on this list touches local development. Compose keeps that job, as the FAQ below spells out.
The compose question is one slice of running containers on Vercel; for the broader set of container workflows, from single images to services, see 7 ways to use Docker containers on Vercel.
Copy link to headingFrequently asked questions
Copy link to headingDo I have to rewrite my compose file to deploy on Vercel?
You translate it once rather than rewrite it. Vercel does not read docker-compose.yml, and no converter tool exists, so you declare each HTTP service by hand under the services key in vercel.json. Your compose file stays untouched and keeps working for local development.
Copy link to headingWhat replaces the volumes in my compose file?
Nothing on Vercel maps to compose volumes directly, because containers on Vercel are stateless. Data that lived in a volume moves to a managed backing service, such as a database or cache from the Vercel Marketplace, and files move to blob storage.
Copy link to headingHow do containers talk to each other without a compose network?
On Vercel, services in the same project call each other through bindings rather than a shared network. The calling service declares a binding, and Vercel injects the target service's URL as an environment variable, so the call never goes through the public internet. The target service stays unreachable from the internet unless a top-level rewrite exposes it.
Copy link to headingCan I still use Docker Compose for local development?
Yes. Deploying to Vercel changes nothing about local tooling, so docker compose up keeps its job. You can also run vercel dev, which runs all of a project's services together with binding environment variables injected; for container images it requires the docker CLI and a running Docker daemon.
Copy link to headingRelated resources
Does Vercel support Docker deployments? in the Knowledge Base
Vercel Services public beta announcement on the Vercel blog
Migrate to Vercel from Fly.io, Railway, Render, or Google Cloud Run