Run a Dockerfile on Vercel
By Flavio Copes
Deploy any HTTP server to Vercel from a Dockerfile.vercel file, test it locally, and understand ports, scaling, storage, and current limitations.
Vercel can now build and run a Dockerfile.
This means you can deploy almost any HTTP server to Vercel, even when Vercel does not support its framework directly.
You add a file named Dockerfile.vercel, and Vercel builds the Docker image, stores it in its container registry, and runs it as a Vercel Function.
Let’s see how it works with a small Node.js server.
Create the HTTP server
Create an empty directory:
mkdir vercel-container
cd vercel-container
Add a server.js file:
const { createServer } = require('node:http')
const port = process.env.PORT || 80
const server = createServer((request, response) => {
response.writeHead(200, {
'content-type': 'application/json',
})
response.end(JSON.stringify({
message: 'Hello from a container on Vercel',
}))
})
server.listen(port, () => {
console.log(`Server listening on port ${port}`)
})
The important part is process.env.PORT.
Vercel sends traffic to the port defined by the PORT environment variable. It defaults to port 80.
Add Dockerfile.vercel
Now create Dockerfile.vercel in the root of the project:
FROM node:24-alpine
WORKDIR /app
COPY server.js .
CMD ["node", "server.js"]
Notice the filename. It must be Dockerfile.vercel, not the usual Dockerfile.
Vercel also detects a file named Containerfile.vercel.
Test it locally
You can run the container with Docker before deploying it:
docker build -f Dockerfile.vercel -t vercel-container .
docker run --rm -p 3000:80 vercel-container
Open http://localhost:3000 and you should see:
{
"message": "Hello from a container on Vercel"
}
You can also use Vercel’s local development server:
npx vercel dev
This requires Docker to be installed and running on your computer.
Deploy the container
Deploy the project with the Vercel CLI:
npx vercel
Vercel detects Dockerfile.vercel, builds the image, pushes it to the Vercel Container Registry, and creates a deployment.
You can also connect the project to a Git repository. Every push then creates a new deployment and a Preview URL, like other Vercel projects.
By default, Vercel routes all traffic for the project to the container.
What happens when traffic stops?
The container does not run forever.
In production, Vercel scales it down after five minutes without traffic. Preview containers scale down after 30 seconds.
Before stopping a container, Vercel sends it a SIGTERM signal and gives it 30 seconds to clean up.
This means your application should handle shutdown correctly if it has work in progress:
process.on('SIGTERM', () => {
server.close(() => {
process.exit(0)
})
})
Containers are stateless
Do not store anything important in the container filesystem.
Vercel can start and stop instances as traffic changes. A file written by one instance will not be available to another instance, and it will disappear when that instance stops.
Store persistent data in a database, object storage service, or cache.
The same Vercel Function limits and Active CPU pricing apply to containers. You pay for CPU while your code is running, not while it waits for I/O.
At the time of writing, Secure Compute and Static IPs are not supported for custom container images.
Why this is useful
Vercel’s automatic framework detection is still the simplest option for supported frameworks.
Dockerfile.vercel is useful when your application:
- uses a framework Vercel does not detect
- needs a system package like FFmpeg or Chromium
- already has a working Docker setup
- runs a Go, Rails, Laravel, FastAPI, Spring Boot, or other HTTP server
If the application listens on $PORT and speaks HTTP, you can now deploy it without setting up your own image registry or container cluster.
Read the official Vercel container images documentation for the current limits and configuration options.
Related posts about docker: