# Run a Dockerfile on Vercel

> Deploy any HTTP server to Vercel from a Dockerfile.vercel file, test it locally, and understand ports, scaling, storage, and current limitations.

Author: [Flavio Copes](https://flaviocopes.com/about/) | Published: 2026-07-30 | Topics: [Docker](https://flaviocopes.com/tags/docker/) | Canonical: https://flaviocopes.com/run-dockerfile-on-vercel/

[Vercel](https://flaviocopes.com/vercel/) can now build and run a [Dockerfile](https://flaviocopes.com/docker-dockerfiles/).

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](https://flaviocopes.com/docker-images/), 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:

```bash
mkdir vercel-container
cd vercel-container
```

Add a `server.js` file:

```js
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:

```dockerfile
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](https://flaviocopes.com/docker-containers/) with Docker before deploying it:

```bash
docker build -f Dockerfile.vercel -t vercel-container .
docker run --rm -p 3000:80 vercel-container
```

Open `http://localhost:3000` and you should see:

```json
{
  "message": "Hello from a container on Vercel"
}
```

You can also use Vercel's local development server:

```bash
npx vercel dev
```

This requires Docker to be installed and running on your computer.

## Deploy the container

Deploy the project with the Vercel CLI:

```bash
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:

```js
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](https://vercel.com/docs/functions/container-images) for the current limits and configuration options.
