# Umzug von Vercel zu einem EU-Hoster

> Eine Next.js-App von Vercel zu blitz.cloud in der EU umziehen: Standalone-Docker-Build, Umgebungsvariablen, Datenbank und was noch nicht mitkommt.

Web page: https://blitz.cloud/de/guides/migrate-from-vercel-to-eu/
Updated: 2026-09-26

Für den Umzug einer Next.js-App von Vercel zu blitz.cloud baust du sie mit `output: "standalone"` zu einem Docker-Image, das auf Port 8080 ohne Root läuft, lädst das Image auf Docker Hub hoch, rollst es auf blitz.cloud aus und überträgst deine Umgebungsvariablen. Die App läuft dann auf Servern in der EU, betrieben von einem deutschen Unternehmen. Ob sich der Tausch lohnt, hängt davon ab, wie viel deine App von Vercels Plattform nutzt. Lies deshalb den nächsten Abschnitt, bevor du anfängst.

## Was sauber umzieht und was noch nicht

Was heute mitkommt:

- Next.js-Apps, die als Node-Server laufen: Server Components, Server Actions, Route Handler in `app/api` und Middleware (seit Next.js 16 "proxy" genannt), die im Node-Server läuft.
- Komplett statische Seiten, auch Builds mit `output: "export"`.
- Umgebungsvariablen und Secrets.
- Eine PostgreSQL-, MySQL/MariaDB- oder Redis-Datenbank, solange die App selbst deine Daten einspielen kann (siehe unten).

Worauf du verzichtest, zumindest vorerst:

- Preview Deployments pro Pull Request. Deploys bei `git push` kommen mit, sobald du GitHub verbindest, aber jeder Push landet in der einen App, nicht in einer Vorschau.
- Deine eigene Domain im kostenlosen Tarif. Eine zu verbinden braucht Pro für 7 EUR im Monat; ohne Pro liegen Apps unter `yourname.blitz.cloud`.
- Ein globales Edge-Netz. blitz.cloud liefert aus einem Rechenzentrum in der EU aus. Besucher in Europa merken nichts, Besucher in Australien schon.
- Edge Functions und Vercel-spezifische Dienste wie Vercel Blob, Edge Config, KV, Cron Jobs und Web Analytics.
- Automatische Bildoptimierung als verwalteter Dienst. `next/image` funktioniert im Standalone-Modus weiter, aber das Skalieren läuft in deiner App und braucht ihren Arbeitsspeicher.
- Skalieren auf null und Abrechnung pro Anfrage. Eine App auf blitz.cloud ist ein dauerhaft laufender Prozess mit 128 MB reserviertem Arbeitsspeicher und einer Obergrenze von 512 MB.

Wenn deine App vor allem von der zweiten Liste lebt, bleib bei Vercel oder schau dir einen Hoster an, der diese Funktionen heute schon hat. Ist deine App ein normaler Next.js-Server mit Datenbank und der Grund für den Umzug ist Hosting in der EU, mach weiter.

## Schritt 1: ein Standalone-Image bauen

Schalte die Standalone-Ausgabe in `next.config.mjs` ein:

```javascript
/** @type {import('next').NextConfig} */
const nextConfig = {
  output: "standalone",
};

export default nextConfig;
```

Lege ein `Dockerfile` neben `package.json` an:

```dockerfile
FROM node:22.23.2-alpine3.24 AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci

FROM node:22.23.2-alpine3.24 AS build
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
ENV NEXT_TELEMETRY_DISABLED=1
RUN npm run build

FROM node:22.23.2-alpine3.24
WORKDIR /app
ENV NODE_ENV=production NEXT_TELEMETRY_DISABLED=1 PORT=8080 HOSTNAME=0.0.0.0
# standalone/ holds server.js and the node_modules it needs; static files and
# public/ are not copied into it by Next, so they are added here.
COPY --from=build --chown=1000:1000 /app/.next/standalone ./
COPY --from=build --chown=1000:1000 /app/.next/static ./.next/static
COPY --from=build --chown=1000:1000 /app/public ./public
USER 1000
EXPOSE 8080
CMD ["node", "server.js"]
```

Und eine `.dockerignore`, damit deine lokale Build-Ausgabe nicht im Image landet:

```text
node_modules
.next
.git
```

`HOSTNAME=0.0.0.0` sorgt dafür, dass der Server auf allen Schnittstellen lauscht statt nur innerhalb des Containers. Mit den `--chown`-Flags darf die App ihren Cache als Benutzer 1000 schreiben.

Wir haben dieses Dockerfile mit Next.js 16.3.5 getestet: Eine Seite, ein Route Handler und eine Datei aus `public/` antworteten alle mit `200`, als Benutzer 1000 und ohne Capabilities. Wenn du pnpm oder yarn nutzt, tausch den Installationsbefehl und den Namen der Lockdatei aus.

## Schritt 2: lokal so testen, wie blitz.cloud es startet

```bash
docker build --platform linux/amd64 -t yourname/my-next-app:1.0.0 -t yourname/my-next-app:latest .
docker run --rm --user 1000:1000 --cap-drop ALL --security-opt no-new-privileges \
  -p 8080:8080 --env-file .env.production.local yourname/my-next-app:1.0.0
```

Klick dich unter http://localhost:8080 durch die App, bevor du weitermachst. Alles, was hier kaputtgeht, etwa eine fehlende Variable oder ein Schreibzugriff auf einen Ordner, den Benutzer 1000 nicht anfassen darf, geht auf blitz.cloud genauso kaputt.

## Schritt 3: die Umgebungsvariablen übertragen

Hol die Produktionsvariablen mit der CLI von Vercel:

```bash
vercel env pull .env.production.local --environment=production
```

Es gibt eine Falle. Variablen, die mit `NEXT_PUBLIC_` beginnen, werden beim Build fest ins JavaScript geschrieben. Sie danach auf blitz.cloud zu setzen, ändert im Browser nichts. Gib sie stattdessen an `docker build` weiter, zum Beispiel mit `ARG NEXT_PUBLIC_API_URL` und `ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL` in der Build-Stufe. Reine Server-Variablen werden beim Start der App gelesen, die kommen in den Tab "Environment" auf blitz.cloud.

Entferne alles Vercel-Spezifische wie `VERCEL_URL` und ersetze Code, der sich darauf verlässt, durch deine neue Adresse.

## Schritt 4: hochladen und ausrollen

Am schnellsten lässt du blitz.cloud aus deinem Repository bauen. Committe Dockerfile und `.dockerignore`, verbinde auf blitz.cloud dein GitHub-Konto, wähl "My own code" und dann Repository und Branch. Danach wird jeder Push gebaut und geht online. Weil der Build auf blitz.cloud läuft, schreib `NEXT_PUBLIC_`-Werte, die nicht geheim sind, mit `ENV` direkt in die Build-Stufe. Trag dann deine serverseitigen Variablen im Tab "Environment" der App ein und starte die App neu.

Wenn du das Image lieber selbst hochlädst:

```bash
docker push --all-tags yourname/my-next-app
```

Das Docker-Hub-Repository muss öffentlich sein. Dein Image enthält deine gebaute App, jeder kann es also herunterladen; halte Secrets aus dem Image heraus und in Umgebungsvariablen.

1. Klicke im [blitz.cloud-Dashboard](https://dashboard.blitz.cloud/) auf "Host something new" (Neues hosten) und wähle "An app from Docker Hub" (eine App von Docker Hub).
2. Suche nach `yourname/my-next-app` und wähle `1.0.0`.
3. Prüfe, dass unter "What this app needs" Port 8080 steht. Nutzt die App eine Datenbank, öffne "Advanced settings" und schalte "Needs a database" ein.
4. Wähle eine Adresse und klicke auf "Put it online".
5. Öffne den Tab "Environment" der App, trag deine serverseitigen Variablen ein und starte die App neu.

## Schritt 5: die Datenbank

Liegt deine Datenbank bei Vercel Postgres, Neon oder Supabase, ist die schonendste Lösung, sie vorerst dort zu lassen und `DATABASE_URL` darauf zeigen zu lassen. Apps auf blitz.cloud dürfen ausgehende Verbindungen aufbauen. Beachte: Damit bleiben deine Daten außerhalb der EU, wenn diese Datenbank außerhalb der EU liegt, und genau das willst du vielleicht beheben.

Um die Daten zu blitz.cloud zu holen, legst du die App mit einer PostgreSQL-Datenbank an und spielst einen Dump aus der App heraus ein. Von deinem Laptop aus kannst du `psql` heute nicht mit einer blitz.cloud-Datenbank verbinden. Ein einmaliger Import muss also Teil der App sein, etwa ein Migrationsskript, das beim ersten Start Daten wiederherstellt. Bei einer großen Datenbank ist das umständlich, und es lohnt sich, auf den Zugriff von außen zu warten.

## Checkliste

- [ ] `output: "standalone"` gesetzt und das Image baut für `linux/amd64`
- [ ] Image läuft lokal mit `--user 1000:1000 --cap-drop ALL`
- [ ] `NEXT_PUBLIC_`-Variablen beim Build übergeben
- [ ] Serverseitige Variablen im Tab "Environment" eingetragen, App neu gestartet
- [ ] Keine reinen Vercel-APIs mehr (Blob, KV, Edge Config, `VERCEL_URL`)
- [ ] Datenbank von blitz.cloud aus erreichbar oder umgezogen
- [ ] Links und OAuth-Callback-URLs auf die neue `*.blitz.cloud`-Adresse umgestellt
- [ ] Altes Vercel-Projekt läuft weiter, bis das neue echten Traffic ausgeliefert hat

## Warum überhaupt umziehen?

Vercel ist ein US-Unternehmen. Daten, die es verarbeitet, fallen deshalb unter US-Recht, einschließlich des CLOUD Act, egal in welcher Region sie liegen. blitz.cloud wird von der BlitzWorks UG (haftungsbeschränkt) in Regensburg auf Servern in der EU betrieben, und weder BlitzWorks noch der Betreiber der Rechenzentren hat einen US-Mutterkonzern. Anfragen an blitz.cloud-Adressen laufen allerdings über Cloudflare, ein US-Unternehmen; eigene Domains nicht. Für manche Teams klärt das eine DSGVO-Frage, für andere ist der Cloudflare-Teil wichtig. Alle beteiligten Anbieter stehen unter [Datenstandort und DSGVO](https://blitz.cloud/de/eu-data/). Einen Funktionsvergleich Seite an Seite gibt es unter [blitz.cloud vs. Vercel](https://blitz.cloud/de/compare/vercel/).
