---
title: Translate Kubernetes manifests to vercel.json
description: Translate Kubernetes Deployments, Services, Ingress, ConfigMaps, and CronJobs into vercel.json configuration and Vercel project settings.
url: /kb/guide/kubernetes-manifests-to-vercel-json
canonical_url: "https://vercel.com/kb/guide/kubernetes-manifests-to-vercel-json"
published: 2026-08-10
last_updated: 2026-08-10
authors: Ben Sabic
related:
  - /docs/cli
  - /docs/container-registry
  - /docs/services
  - /docs/environment-variables
  - /docs/cron-jobs/manage-cron-jobs
  - /docs/vercel-blob
  - /docs/observability
  - /docs/project-configuration/vercel-json
  - /docs/functions/container-images
install_vercel_plugin: npx plugins add vercel/vercel-plugin
---

Kubernetes describes a workload across several manifests, while Vercel describes the same workload with a `Dockerfile.vercel`, a `vercel.json` file, and project settings. Most of the YAML disappears in translation because Vercel handles scheduling, scaling, and routing for you.

This guide takes the manifests behind a typical containerized HTTP service, including the Deployment, Service, Ingress, ConfigMap, and CronJob, and shows the equivalent configuration on Vercel.

## Overview

In this guide, you'll learn how to:

- Translate a Deployment into a container image that runs as a Vercel Function
  
- Translate Services and Ingress rules into Vercel Services and rewrites
  
- Move ConfigMaps and Secrets into environment variables
  
- Translate CronJobs into the `crons` array in `vercel.json`
  
- Map resource requests, limits, and placement to function settings
  

## Prerequisites

- Working Kubernetes manifests for the workload you're translating
  
- The container image or Dockerfile that the Deployment references
  
- [Vercel CLI](https://vercel.com/docs/cli) installed and a linked Vercel project
  

## Steps

### 1\. Translate the Deployment

Your Deployment's Pod spec becomes a `Dockerfile.vercel` (or `Containerfile.vercel`) at the root of your project. Vercel detects the file, builds the image during deployment, pushes it to [Vercel Container Registry](https://vercel.com/docs/container-registry), and adds a rewrite that routes all traffic to it.

Start from a minimal Deployment:

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
spec:
  replicas: 3
  template:
    spec:
      containers:
        - name: api
          image: registry.example.com/api:1.4.2
          ports:
            - containerPort: 8080
```

The entire Pod spec reduces to a `Dockerfile.vercel` that produces the same image:

```dockerfile
FROM registry.example.com/api:1.4.2
```

Three fields from the Deployment need attention:

- `**replicas**` **and any HorizontalPodAutoscaler**: Delete them. Vercel Functions scale up with traffic and scale down when idle, with no replica count to manage. In production, an instance with no traffic for 5 minutes scales down and receives a `SIGTERM` with a 30s grace period; preview instances scale in after only 30s of no traffic, so expect faster recycling while testing on previews. Keep any `preStop`\-style cleanup in your existing signal handlers.
  
- `**containerPort**`: Vercel routes traffic to port 80 by default. If your server listens elsewhere, such as the 8080 in this Deployment, set the `PORT` environment variable in your project settings.
  
- **Liveness and readiness probes**: Remove them. There is no probe configuration on Vercel; the platform manages the instance lifecycle for you.
  

### 2\. Translate Services and Ingress

Ingress path rules become `rewrites` in `vercel.json`, and ClusterIP Services that connect workloads become [Vercel Services](https://vercel.com/docs/services) within one project.

Consider an Ingress that splits traffic between a frontend and an API:

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
spec:
  rules:
    - http:
        paths:
          - path: /api
            backend:
              service:
                name: api
          - path: /
            backend:
              service:
                name: frontend
```

The same routing translates to a services block with rewrites in `vercel.json`:

```json
{
  "$schema": "https://openapi.vercel.sh/vercel.json",
  "services": {
    "frontend": { "root": "frontend/" },
    "api": { "runtime": "container", "root": "api/" }
  },
  "rewrites": [
    { "source": "/api/(.*)", "destination": { "service": "api" } },
    { "source": "/(.*)", "destination": { "service": "frontend" } }
  ]
}
```

Each service builds independently and can use a different runtime or framework. Set `"runtime": "container"` on any service that should build from its Dockerfile. Routing keys such as `rewrites` stay at the top level of `vercel.json` because they own public traffic for the whole deployment.

### 3\. Translate ConfigMaps and Secrets

ConfigMap and Secret values both become [environment variables](https://vercel.com/docs/environment-variables), scoped to the production, preview, or development environment. There is no separate secret object; sensitive values can be marked as sensitive in the dashboard.

For a Pod that consumed configuration with `envFrom`, add each key with the CLI:

```bash
vercel env add DATABASE_URL production
```

Then sync your local environment instead of maintaining a local Secret copy:

```bash
vercel env pull
```

Each environment supports up to 1,000 variables. The documented 64 KB total size limit for names and values applies to the managed runtimes. Values that exceed that limit, such as large certificates, belong in external storage rather than environment variables.

### 4\. Translate CronJobs

Each Kubernetes CronJob becomes an entry in the `crons` array, pointing at a path on your deployment. Vercel triggers the job with an HTTP GET request to that path on your production deployment.

Take a CronJob that runs a nightly cleanup:

```yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: nightly-cleanup
spec:
  schedule: "0 5 * * *"
```

The equivalent `crons` entry looks like this:

```json
{
  "$schema": "https://openapi.vercel.sh/vercel.json",
  "crons": [
    { "path": "/api/cleanup", "schedule": "0 5 * * *" }
  ]
}
```

Two schedule-syntax differences will break a direct copy: Vercel doesn't support alternative expressions like `MON` or `JAN`, and you can't set day of the month and day of the week in the same expression. Rewrite any schedule that uses either pattern.

Kubernetes CronJobs run inside the cluster, but Vercel cron paths are HTTP endpoints, so secure them. Add a `CRON_SECRET` environment variable to your project, and Vercel sends it on every invocation in the `Authorization` header with a `Bearer` prefix, so compare against `Bearer ${CRON_SECRET}` rather than the raw value. See [Managing Cron Jobs](https://vercel.com/docs/cron-jobs/manage-cron-jobs) for the verification pattern.

### 5\. Translate resource requests, limits, and placement

Kubernetes resource stanzas map to function settings rather than `vercel.json` fields in most cases.

CPU and memory requests have no `vercel.json` field. With Fluid compute enabled, set memory in the **Functions** section of your project dashboard.

Execution limits translate to the `functions` property, which caps how long a route can run:

```json
{
  "$schema": "https://openapi.vercel.sh/vercel.json",
  "functions": {
    "api/**": { "maxDuration": 60 }
  }
}
```

If your project defines `services` as in Step 2, the `functions` block moves inside the relevant service object instead of sitting at the top level, since services mode changes which keys are valid where.

Node affinity and topology translate to the `regions` key, which pins where functions execute, and individual functions can override it. This replaces node selectors for latency or data-residency placement.

## What has no `vercel.json` equivalent

Some manifests describe cluster machinery rather than the workload, and they have no translation target:

- **StatefulSets and PersistentVolumeClaims**: Functions are stateless. Move durable data to [Vercel Blob](https://vercel.com/docs/vercel-blob) or a [Marketplace database](https://vercel.com/marketplace).
  
- **DaemonSets**: There are no nodes to run per-node agents on. Logging and metrics are built into [Vercel Observability](https://vercel.com/docs/observability).
  
- **NetworkPolicies and service meshes**: Traffic between Vercel Services is routed by the platform, with no user-defined east-west policy.
  
- **Operators and custom resources**: Anything that extends the Kubernetes API either stays on the cluster or moves to a managed service.
  

## Troubleshooting

### The container deploys but receives no traffic

Check the port. Vercel sends traffic to port 80 unless the `PORT` environment variable says otherwise. If your server is still listening on its Kubernetes `containerPort` value, such as 8080, it appears deployed but stays unreachable until `PORT` matches.

### Environment variables are missing locally

Run `vercel env pull` after adding or changing variables if your framework's dev server reads the pulled `.env.local` file. If you develop with `vercel dev`, Development variables are pulled automatically without a manual sync.

### The cron job never fires

Check the expression for `MON`\-style aliases or a combined day-of-month and day-of-week rule, since both are unsupported. Also confirm you're checking the production deployment, because cron invocations target the production URL.

## Next steps

- Review every available field in the [vercel.json reference](https://vercel.com/docs/project-configuration/vercel-json)
  
- Read the [container images documentation](https://vercel.com/docs/functions/container-images) for the execution model and limits
  
- Learn how [Vercel Services](https://vercel.com/docs/services) route traffic between backends and frontends