Vercel Brings Back Docker Deploys via Serverless Containers
By packaging containers as serverless functions, Vercel opens its platform to non-JS backends and custom runtimes.
In the early days of Vercel, back when it was known as Now.sh, you could deploy a raw Dockerfile with a single command. It was a beloved feature that made the platform a playground for polyglot backends. But in 2020, Vercel quietly retired container support, focusing instead on serverless functions, frontend frameworks, and the Next.js ecosystem. The infrastructure of the time simply could not handle the economic and operational realities of running arbitrary, long-running containers at scale.
Six years later, containers are back. Vercel has introduced support for deploying arbitrary Dockerfiles directly to its platform. By adding a Dockerfile.vercel file to a repository, developers can build, store, and run containerized applications on Vercel's infrastructure.
This is not just a nostalgic rollback. It is a calculated expansion of Vercel's addressable market, targeting workloads that previously forced developers to look toward dedicated container hosts like Fly.io, AWS ECS, or Google Cloud Run. But while the developer experience feels like the classic Now.sh, the underlying architecture has been completely rebuilt on top of modern serverless primitives.
Serverless in Container's Clothing
To understand how to use this feature effectively, you must understand what is happening under the hood. Vercel is not provisioning a persistent virtual machine or a traditional Kubernetes pod for your container. Instead, it compiles your Dockerfile, stores the resulting OCI-compatible image in the Vercel Container Registry (VCR), and executes it as a Vercel Function on what they call Fluid compute.
This architectural choice introduces several unique behaviors and constraints:
- On-Demand Streaming Decompression: Traditional container runtimes download the entire image before booting. To combat cold starts, Vercel stores your image as an optimized boot image, which is a compressed snapshot of the container's disk. When a container boots, the platform streams and decompresses this snapshot on demand. This allows the container to start handling HTTP requests before the entire image is fully downloaded.
- Active CPU Pricing: Traditional container hosting charges you for wall time, meaning you pay for the container as long as it is provisioned, even if it is sitting idle waiting for requests. Vercel charges only for active CPU execution time. If your container is parked waiting on a slow database query or an upstream API, you are not billed for idle CPU cycles.
- Scale-to-Zero: If a container receives no traffic for five minutes in production (or 30 seconds in preview environments), it scales down to zero. When a new request arrives, it triggers a cold start.
- Stateless Execution: Like standard serverless functions, these containers are entirely stateless. Any local disk writes are ephemeral. Persistent state must be offloaded to external databases, caches, or third-party storage providers.
The Developer Angle: Multi-Service Architecture
For developers, the immediate benefit is the ability to run non-JavaScript backends, such as Go, Rails, Spring Boot, Laravel, or Python's FastAPI, alongside their frontends on a single platform.
To deploy a container, you define a Dockerfile.vercel (or Containerfile.vercel) at the root of your project. The only strict requirement is that your containerized application must run an HTTP server that listens on the port specified by the $PORT environment variable, which defaults to 80.
For complex applications, the real power lies in Vercel's multi-service routing. Using vercel.json, you can define multiple services, each with its own Dockerfile, and route traffic between them. This allows you to run a Next.js frontend and a Go backend in the same project, sharing environment variables and communicating over a private network.
Here is an example of a vercel.json configuration that orchestrates a frontend and a backend service:
{
"services": {
"frontend": {
"root": "frontend/",
"entrypoint": "Dockerfile.vercel"
},
"backend": {
"root": "backend/",
"entrypoint": "Dockerfile.vercel"
}
},
"rewrites": [
{
"source": "/api/(.*)",
"destination": {
"service": "backend"
}
},
{
"source": "/(.*)",
"destination": {
"service": "frontend"
}
}
]
}
This setup routes all API requests to the backend container while serving the frontend from another. During local development, running vercel dev will spin up both services locally, provided you have the Docker CLI and daemon running on your machine.
To verify builds locally without pushing to Git, you can run:
vercel build
vercel deploy --prebuilt
This compiles the assets locally and uploads the prebuilt output directly to Vercel, bypassing the remote build step.
The Trade-offs and Missing Pieces
While the developer experience is highly polished, running containers as serverless functions introduces distinct trade-offs that make them unsuitable for certain workloads.
First, the platform enforces strict lifecycle limits. When a container is scaled down due to inactivity, it receives a SIGTERM signal. The application has a hard 30-second grace period to finish processing active requests and clean up resources before Vercel terminates the instance. If your application relies on long-running background jobs or WebSockets that require persistent open connections, this model will fail.
Second, containerized functions inherit the same execution limits as standard Vercel Functions regarding maximum memory, payload size, and execution duration. If you are processing massive video files or running heavy machine learning inference, you will quickly hit these ceilings.
Finally, two critical networking features are currently unsupported for custom container images:
- Secure Compute: You cannot currently use dedicated network isolation to connect to backends over a private connection.
- Static IPs: You cannot assign fixed outbound IP addresses to your containers, which is a common requirement when integrating with enterprise APIs or databases that require IP allowlisting.
If your application depends on either of these networking features, you must stick to standard Vercel Functions or host those specific workloads on a traditional container platform.
The Verdict
Vercel's return to Docker is a pragmatic acknowledgment that the web is polyglot. While framework detection and zero-configuration deployments work beautifully for standard frontend stacks, they fall short when an application requires system-level dependencies like FFmpeg, or when a team wants to migrate an existing microservice without rewriting it in Node.js.
This feature is not a replacement for dedicated container orchestrators like AWS ECS or Kubernetes for high-throughput, low-latency, or stateful backend systems. However, for teams already committed to the Vercel ecosystem who want to consolidate their stack, run lightweight non-JS APIs, or deploy utility containers without managing separate infrastructure, it is an incredibly compelling addition to the toolbelt.
Sources & further reading
- Run any Dockerfile on Vercel — vercel.com
- Run any Dockerfile on Vercel | Lobsters — lobste.rs
- dockette/vercel - Docker Image — hub.docker.com
- Does Vercel support Docker deployments? — examples.vercel.com
- GitHub - gastonpereyra/vercel-docker: Some tools or advices to use vercel and docker for local development · GitHub — github.com
Ji-ho covers the increasingly tangled overlap between cloud architecture and security, drawing on a background as a penetration tester to keep his reporting grounded in real-world attack paths. He never lets a vendor claim go unquestioned and insists that every buzzword come with a proof of concept.
Discussion 0
No comments yet
Be the first to weigh in.