> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ankra.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Vercel to Ankra

> Move a Vercel project, usually Next.js, onto your own Kubernetes cluster - start from the Vercel project page with the Ankra Chrome extension, review one Launch Plan that says per service what stays at Vercel and what Ankra runs open source, approve once, and keep API routes, middleware, cron jobs and environment variables working.

Vercel builds and serves your project from its own platform. Ankra builds the same GitHub repository and runs it on your own cluster, behind HTTPS, with every change built and scanned first.

You keep pushing to the same repository. Ankra builds every commit.

***

## What moves, and what it becomes

| On Vercel | On Ankra |
| - | - |
| Next.js build | One container image. When `next.config` sets `output: 'standalone'`, the image carries only the standalone server, its static assets and `public/`. Otherwise it runs `next start` |
| API routes, route handlers, middleware, edge routes | Served by the Next.js server in that container. Nothing to split out |
| `vercel.json` crons | One Kubernetes CronJob per cron entry. It calls the same route on the same UTC schedule, with the `vercel-cron/1.0` user agent and `Authorization: Bearer <CRON_SECRET>` when the app has a `CRON_SECRET` secret, so a route that checks it keeps working |
| `vercel.json` rewrites, redirects and headers | Listed in the setup pull request. Vercel applied them at its edge; on Ankra your own server serves every request, so they have to live in `next.config` (`rewrites()`, `redirects()`, `headers()`) before you move traffic. Ask for the [next.config pull request](#the-nextconfig-pull-request) to have Ankra move them |
| Project environment variables | The application's environment secrets. Bring them over with the extension (below) or enter them in Ankra |
| Preview deployments | [Preview demos](/concepts/applications.md#preview-demos) on a preview address. The proof run of the setup pull request is compared with Vercel's preview of the same commit ([below](#compared-with-your-vercel-preview)) |
| Your domain | Your own domain with its certificate on the cluster ([Applications](/concepts/applications.md)) |

The setup pull request contains the Dockerfile, the Kubernetes manifests, the CronJobs, the deploy options (`.ankra/ankra.yaml`) and the build pipeline (`.ankra/pipeline.yaml`). Ankra's AI writes it when you add the repository. You review and merge it.

***

## Vercel storage in the Launch Plan

Ankra reads which Vercel storage the code uses and puts one card per service in the project's Launch Plan. Each card shows how locked in the service is and which choice applies by default. You can change the choice.

| Vercel service | Default | What you can choose instead |
| - | - | - |
| Vercel Postgres (`@vercel/postgres`) | Keep it: `POSTGRES_URL` stays an environment secret | A portability pull request switches to a plain Postgres driver on one connection string, then Ankra runs CloudNativePG in your cluster |
| Vercel KV (`@vercel/kv`) | Keep it | A portability pull request moves to a Redis client on `REDIS_URL`, backed by Valkey in your cluster |
| Vercel Blob (`@vercel/blob`) | Keep it | A portability pull request moves uploads to the S3 API, backed by object storage in your cluster |
| Edge Config (`@vercel/edge-config`) | Keep it | A portability pull request reads the same keys from environment variables, delivered as a ConfigMap |

A portability pull request is opt-in. It adds the open-protocol path beside Vercel's, and the app keeps using Vercel until you set the new variables. Data is copied only when you start a [data migration](#moving-your-data-closed-beta).

***

## Portability pull requests

A portability pull request is a small change to your code that Ankra opens on your repository only when you ask for it. Ankra opens two kinds:

* **A service's portability pull request.** It adds the open-protocol path for a Vercel storage service from the table above, beside Vercel's.
* **The next.config pull request.** It moves your `vercel.json` routing into `next.config`.

### Asking for one

Each portability pull request is an action of the project's Launch Plan, and a plan-level approval covers it like any other action:

1. For a storage service, choose the portability pull request on its card. A Vercel project always offers the next.config pull request.
2. Select the pull request among the actions you approve. It is never selected for you.
3. Open it under the approval with **Open an approved portability pull request** in the [API reference](/api-reference/introduction.md). It needs `applications.write`. Only you, the approver, can open it, and each approved pull request opens once.

The request answers straight away with the operation that opens the pull request. Ankra reads your repository at the commit the plan was made from and opens the pull request from there. If the branch has moved on since, nothing is opened: analyse the application again and approve the new plan.

### When a person has to make the change

Ankra changes only what it can change with confidence. If it cannot, it opens nothing. The operation fails with the reason, starting with `needs a person:`, for example when `next.config` already defines `redirects()`. Make that change yourself.

### The next.config pull request

The next.config pull request moves the redirects, rewrites and headers from `vercel.json` into `next.config`, and sets `output: 'standalone'` so the image carries only the standalone server. Your existing configuration is kept as it is: the pull request only adds to it. While Vercel builds the app, the moved rules return nothing, so `vercel.json` keeps serving your routing on Vercel until you move traffic.

### After it opens

The [PR shepherd](/concepts/applications.md#the-pr-shepherd) follows every portability pull request and drives it to ready. Ankra never merges a portability pull request, whatever your merge settings, because it changes your code. You review and merge it.

***

## Moving your data (Closed Beta)

> [!WARNING]
>
> **Closed beta.** Data migration is in closed beta. Where Ankra cannot yet carry out a step for a service, the run stops before anything at the vendor changes, or rolls back, and gives the reason. [Contact support](/platform/support.md) before relying on it for a production move.

When you choose to move a service into your cluster, the Launch Plan carries a data migration for it. The migration plans the move in steps, and one plan-level approval covers all of them.

Every service moves before one cutover:

1. Ankra copies the data in while your app keeps running on Vercel.
2. It makes each vendor source read-only.
3. It copies what changed since the first copy and checks counts and checksums.
4. It switches your app's variables to the services in your cluster in one change.

The vendor sources then stay read-only for a rollback window, seven days by default. In that window, one command puts the previous variables back and makes the sources writable again. Ankra never deletes data at the vendor. When the window closes, you get a checklist of what to remove there yourself.

| Service | How the data moves |
| - | - |
| Postgres | Ankra reads the source with the connection string you stored, to choose how it moves. It dumps the read-only source into one of your [backup vaults](/guides/backups.md) and restores the dump into CloudNativePG, then compares row counts and sequences |
| S3-compatible object storage | Every object is copied with its checksum checked, then copied again right before the cutover |

```bash theme={null}
# follow the runs, and roll one back inside its window
ankra application data-migration list <application>
ankra application data-migration get <application> <run-id>
ankra application data-migration rollback <application> <run-id>
```

Vercel Blob is not S3-compatible, so its data is not copied yet.

***

## Compared with your Vercel preview

Before you merge the setup pull request, Ankra's proof run deploys it to an ankra.cc preview and requests its health routes and its home page. For a Vercel project, the proof then requests the same routes on the preview Vercel deployed of the same commit, and compares the two answers.

The comparison looks at the shape of each answer, not its exact bytes:

* the status code
* the content type
* for JSON, the keys two levels deep
* for an HTML page, its title and which of `header`, `nav`, `main` and `footer` it has
* the size, which counts as different only when one answer is more than twice the other

Build ids, nonces and timestamps differ between any two deployments, so they are not compared.

Each route gets one of three results on the proof card in the pull request:

| Result | Meaning |
| - | - |
| **match** | Both previews answered with the same shape |
| **differs** | Both answered, differently. The card names the first difference, for example a different status or page title |
| **unknown** | The routes were not compared. The card says why, for example: Vercel deployed no preview of the commit, the preview was still building, the preview is protected, or a request timed out |

An unknown route is never counted as a match.

A difference is a warning. It does not fail the proof and does not block the pull request. A Vercel preview can differ for good reasons, such as variables set only for previews. Check each difference before you move your domain.

Ankra finds the Vercel preview from the deployment status Vercel's GitHub integration posts on the commit, so the GitHub App Ankra uses must be able to read the repository's deployments. Ankra sends no credential to the Vercel preview. If the preview is protected by Vercel Authentication, its routes show as unknown.

***

## Start from the Vercel project page

The **Ankra — Chat & Deploy** extension for Chrome puts an **Ask Ankra** button on your Vercel project page, and also on Lovable, Claude Design and GitHub repository pages. See [install the extension](/use-cases/lovable-to-ankra.md#install-the-extension-without-the-chrome-web-store).

**1. See where the project stands**

The button carries a status pill for the project's repository: **Not connected**, **Analysing**, **N decisions**, **Ready to approve**, **Proving**, **Proof failed** or **Live**. The same pill appears on the repository's GitHub pages.

**2. Review the Launch Plan**

Open **Deploy project**. The extension fills in the GitHub repository the Vercel project builds and its branch. The **Launch Plan** panel lists:

* the decisions only you can make, with their defaults
* per external service, what stays at Vercel and what Ankra runs open source
* the result of the proof run of the setup pull request

To change a decision, use **Change decisions in Ankra**. All configuration stays in Ankra.

**3. Bring your variables**

Under **Bring variables from Vercel**, paste a Vercel access token for the project's team and choose **Read variables**. The token is used from your browser only and is not stored or sent to Ankra.

By default you get the names of the project's production variables, marked by whether Ankra already has each one. Tick the box to copy the values into the application's encrypted secrets. Values Ankra already holds are never overwritten. Variables marked sensitive on Vercel cannot be read back, so enter those in Ankra.

Values can be copied once Ankra has registered the application, which happens on the first deploy.

**4. Approve**

Click **Approve and deploy**. Ankra registers the application, opens the setup pull request, builds and scans the image, and deploys it with the plan's choices. If the setup pull request or the first build is still pending, the request waits and is sent when Ankra is ready.

The approval covers exactly the actions the panel lists, for one hour. When Ankra AI works on the launch in your chat or in an agent run that carries the approval, it runs those actions without asking you again. Anything outside the list still asks first. If the plan changes after you approve, nothing runs under the old approval: read the new plan and approve it.

> [!NOTE]
>
> Test on the Ankra address before you move your domain. Check every route the proof card shows as differing or unknown, the cron routes, the rewrites you moved into `next.config`, and every variable your app reads.

***

## From the CLI

```bash theme={null}
ankra application add . --branch main
ankra chat "show me the Launch Plan of <application>" --mode ask
```

Run the first command in a local checkout of the repository.

See [Applications](/concepts/applications.md) and [Lovable to Ankra](/use-cases/lovable-to-ankra.md) for the rest of the flow, from the setup pull request to automatic deploys.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.