Umzug von Vercel
Schritt für Schritt von Vercel zu gooddeploy: Next.js-App mit Postgres und eigener Domain, ohne dass die Seite ausfällt. Vercel läuft weiter, bis bei gooddeploy alles geprüft ist; am Ende steht eine Checkliste zum Abhaken.
Überblick
So läuft der Umzug eines Projekts ab:
- Zugang und CLI einrichten,
- Projekt vorbereiten,
- Variablen von Vercel übernehmen,
- Datenbank wählen: Postgres bei gooddeploy oder die bisherige behalten,
- erstes Deploy und prüfen,
- Kunden abnehmen lassen,
- live schalten,
- eigene Domain umstellen,
- Vercel abschalten, erst wenn alles läuft.
Bis Schritt 8 ändert sich für Besucher nichts: Die Domain zeigt weiter auf Vercel. Hast du viele kleine Seiten, ziehst du sie einzeln um, eine nach der anderen; jede bekommt ein eigenes gooddeploy-Projekt.
1. Zugang und CLI
In der Pilotphase richtet goodDEV deinen Zugang ein: Schreib an gooddeploy@gooddev.de, du bekommst einen Zugang für deine E-Mail-Adresse in einem Team. Selbst registrieren geht noch nicht.
curl -fsSL https://gooddeploy.de/install.sh | sh
gooddeploy version
gooddeploy login --email du@agentur.de
gooddeploy whoami
Für den Umzug brauchst du mindestens Version 0.0.3-alpha.3 (wegen env import); eine ältere holst du mit gooddeploy update. login zeigt einen Code und schickt dir eine E-Mail mit einem Link; dort gibst du den Code ein. Alles Weitere unter Testzugang. Betreust du Projekte in mehreren Teams (z. B. ein Team je Kunde), meldest du dich mit --team "<Name>" für das richtige Team an (siehe Mehrere Teams).
Für Schritt 3 brauchst du außerdem die Vercel-CLI, angemeldet und mit dem Vercel-Projekt verknüpft (vercel link im Projektordner).
2. Projekt vorbereiten
gooddeploy baut genau den letzten Commit (HEAD), nicht deine Arbeitskopie. Prüfe im Projektordner:
- Alles ist committet, das Lockfile auch (
package-lock.json,pnpm-lock.yamloderyarn.lock). next buildund danachnext startlaufen lokal ohne Fehler.- Die Node-Version steht in
engines.nodederpackage.json. - Keine Git-Submodule und kein Git LFS; Bun als Paketmanager geht noch nicht (siehe Was gebaut werden kann).
Next.js
- Setze in der
next.configoutput: "standalone": kleineres Image, schnellerer Start. Ohne läuft die App auch,deployweist dich dann mit⚠darauf hin. - Migrationen: gooddeploy startet die App mit
node server.js, nicht mitnpm start. Einstart-Skript wieprisma migrate deploy && next startläuft deshalb nicht. Sollen Migrationen beim Start laufen, geht das heute mit einer eigenenserver.js, dann aber ohneoutput: "standalone". Wie das geht, steht unter Migrationen ausrollen. - Build-Variablen:
NEXT_PUBLIC_…werden beim Build in das JavaScript eingebaut. Sie müssen in Previews und Live gleich sein, sonst lehntpromoteab (BUILD_ENV_MISMATCH). Unterscheiden sie sich bei Vercel (z. B.NEXT_PUBLIC_SITE_URL), wähle für beide Umgebungen denselben Wert oder lies die Adresse zur Laufzeit. - Seiten, die beim Build die Datenbank abfragen, brechen ab: Beim Build gibt es keine Datenbank. Mach sie dynamisch (siehe Häufige Fehler).
- Weiterleitungen: Stehen in deiner
vercel.jsonredirects, zieh sie in dieredirects()dernext.configum; die gelten bei gooddeploy unverändert. Für statische Seiten (auch Next.js mitoutput: "export") übernimmst du sie in diegooddeploy.json, siehe Weiterleitungen. - Vercel-eigene Dienste wie Vercel Blob, Global Config (früher Edge Config), Web Analytics oder Cron-Jobs aus
vercel.jsongibt es bei gooddeploy nicht. Schreib sie auf eine Liste und kläre vorher, wie du sie ersetzt (siehe Was es noch nicht gibt).
Große Dateien ausschließen
Agentur-Repos enthalten oft Dateien, die die Seite nicht braucht. Über 100 MB (komprimiert) lehnt gooddeploy den Upload ab. Leg eine .gooddeployignore im Projekt-Root an, gleiche Syntax wie .gitignore:
docs/
design/
*.psd
*.fig
**/raw/
*.mov
git add .gooddeployignore
git commit -m "gooddeploy: große Dateien beim Upload weglassen"
Die Datei muss committet sein, gooddeploy liest sie aus dem Commit. Details unter Große Dateien ausschließen.
3. Variablen von Vercel übernehmen
Zuerst verknüpfst du den Ordner mit einem neuen gooddeploy-Projekt. Ob du dabei Postgres anlegst, entscheidest du in Schritt 4; lies ihn also vorher.
gooddeploy link kunde-website
link fragt, ob es das Projekt anlegen soll, und danach „Postgres anlegen?“. Projektnamen haben 3 bis 30 Zeichen: Kleinbuchstaben, Ziffern, Bindestriche.
Dann holst du die Variablen je Umgebung von Vercel und übernimmst sie. Ohne --environment holt vercel env pull die Werte für Development, deshalb gibst du die Umgebung immer an (Quelle: Quellen zu Vercel):
vercel env pull --environment=production .env.vercel-production
gooddeploy env import .env.vercel-production --production
vercel env pull --environment=preview .env.vercel-preview
gooddeploy env import .env.vercel-preview --preview
rm .env.vercel-production .env.vercel-preview
Nimm je Umgebung eine eigene, neue Datei: Gibt es die Datei schon, ergänzt vercel env pull sie nur, und Werte der anderen Umgebung blieben stehen. Sind die Werte in beiden Umgebungen gleich, reicht ein Import mit --both. env import zeigt vorher nur die Namen, nie die Werte, und fragt, bevor es etwas setzt:
Aus .env.vercel-production nach kunde-website (Live), nur Namen:
API_URL: neu
STRIPE_SECRET_KEY: neu
NEXT_PUBLIC_SITE_URL: neu, Build-Variable
DATABASE_URL: übersprungen: setzt gooddeploy für die eigene Datenbank; eine externe einzeln mit gooddeploy env add DATABASE_URL
VERCEL_OIDC_TOKEN: übersprungen: Variable von Vercel
? 3 Variable(n) in kunde-website setzen? (J/n)
✓ 3 Variable(n) aus .env.vercel-production in kunde-website gesetzt
Übersprungen werden mit Hinweis:
| Was | Warum | Was du tust |
|---|---|---|
DATABASE_URL, DATABASE_URL_UNPOOLED | gooddeploy setzt sie für die eigene Datenbank | nichts, oder bei externer Datenbank einzeln setzen (Schritt 4) |
VERCEL, VERCEL_…, TURBO_… | Variablen von Vercel selbst, bei gooddeploy ohne Bedeutung | nichts; nutzt dein Code z. B. VERCEL_URL, ersetze es durch eine eigene Variable |
PORT, NODE_ENV, HOSTNAME, GOODDEPLOY_… | setzt gooddeploy selbst | nichts |
| mehrzeilige Werte (z. B. private Schlüssel) | gooddeploy unterstützt sie noch nicht | Base64-kodiert in einer Zeile setzen und in der App dekodieren |
| leere Werte, ungültige Namen | Namen nur aus A-Z, 0-9 und _ | prüfen, ob du sie brauchst |
Einen mehrzeiligen Wert setzt du so (hier ein Schlüssel aus einer Datei, macOS und Linux):
base64 < private-key.pem | tr -d '\n' | gooddeploy env add PRIVATE_KEY_BASE64 --both
In der App: Buffer.from(process.env.PRIVATE_KEY_BASE64 ?? "", "base64").toString("utf8").
Achtung, geheime Werte bei Vercel: Variablen vom Typ „Secret“ (früher „Sensitive“) gibt Vercel nach dem Speichern nicht mehr heraus, und legst du Variablen für Production oder Preview mit der Vercel-CLI an, ist „Secret“ der Standard. Rechne also damit, dass viele Werte fehlen:
vercel env pullschreibt für sie einen Platzhalter statt des echten Werts in die neue Datei (siehe Quellen zu Vercel).env importerkennt solche Platzhalter nicht und würde sie übernehmen. Sieh dir die Dateien deshalb vor dem Import an und lösch die Zeilen ohne echten Wert. Diese Variablen setzt du einzeln mitgooddeploy env add NAME --bothaus deinem Passwortmanager oder dem Konto des jeweiligen Dienstes.
Prüfen, was angekommen ist (Werte maskiert):
gooddeploy env ls
Alles zu den Befehlen unter Umzug von Vercel: env import. Lösch die Dateien nach dem Import; sie enthalten deine Geheimnisse und gehören nie ins Git.
4. Datenbank
Du hast zwei Wege. Entscheide vor gooddeploy link, denn Postgres legst du derzeit nur beim Anlegen des Projekts selbst an; nachträglich richtet goodDEV sie für dich ein.
Weg A: Postgres bei gooddeploy
Beim Anlegen „Postgres anlegen?“ mit Enter bestätigen (im Skript: gooddeploy link kunde-website --yes --postgres). Deine App bekommt dann bei jedem Start DATABASE_URL (über einen Verbindungs-Pool) und DATABASE_URL_UNPOOLED (für Migrationen), dieselben Namen wie bei Vercel und Neon. Live hat eine eigene Datenbank, alle Previews teilen sich eine zweite. Prisma und Drizzle einrichten: Datenbank in deiner App nutzen.
Daten übernehmen: Die Datenbank bei gooddeploy ist nur aus deiner App erreichbar, nicht von deinem Rechner, und einen Befehl zum Einspielen einer Sicherung gibt es noch nicht (kommt später, ebenso ein Umzug direkt aus der alten Datenbank in einem Schritt). Bis dahin spielt goodDEV deine Daten ein.
Zieh eine Sicherung der bisherigen Datenbank im Format von pg_dump -Fc:
pg_dump -Fc "<bisherige Verbindungs-URL>" -f kunde-website.dump
- Nimm dafür die direkte Adresse ohne Pool (bei Neon die URL ohne
-pooler). Deinpg_dumpsollte mindestens die Hauptversion der Quelle haben; bei gooddeploy läuft Postgres 17. - Gib die Datei sicher an goodDEV, nicht als E-Mail-Anhang; den Weg sprechen wir mit dir ab. Wir spielen sie in die Live-Datenbank ein und sagen dir Bescheid.
- Plane dafür einen Zeitpunkt, an dem auf der alten Seite niemand Daten ändert, oder gleiche später ab. Alles, was nach dem Dump bei Vercel geschrieben wird, fehlt sonst bei gooddeploy.
Prüfen kannst du danach mit gooddeploy db info (Größe, Verbindungen) und gooddeploy db dump -o kontrolle.dump (Sicherung der Live-Datenbank herunterladen). Automatische Backups gibt es in der Testphase noch nicht: Sichere wichtige Daten selbst mit gooddeploy db dump.
Weg B: bisherige Datenbank behalten
Nutzt du Neon, Supabase oder eine andere externe Postgres-Datenbank, kann sie bleiben. Antworte bei „Postgres anlegen?“ mit n und setze die Adresse selbst, je Umgebung (Eingabe verdeckt):
gooddeploy env add DATABASE_URL --production
gooddeploy env add DATABASE_URL --preview
Brauchen deine Migrationen eine direkte Adresse ohne Pool, setze DATABASE_URL_UNPOOLED genauso. Nimm für Previews eine eigene Datenbank oder einen eigenen Zweig, nicht die Live-Datenbank. Ob die App die Datenbank erreicht, siehst du an der ersten Preview (Seite mit Daten öffnen, sonst gooddeploy logs <id>). Lässt dein Anbieter nur bestimmte IP-Adressen zu, frag goodDEV. Der Vertrag für die Datenbank bleibt beim jeweiligen Anbieter. Ein eigener Befehl, der eine externe Datenbank anbindet und die Verbindung prüft, kommt später; bis dahin geht es mit env add.
5. Erstes Deploy
gooddeploy deploy
gooddeploy lädt den letzten Commit hoch, baut ihn, startet die App und prüft, ob sie antwortet. Previews sind geschützt; deploy erzeugt dir deshalb gleich einen Freigabelink, der 1 Tag gilt:
✓ Preview bereit nach 48 s
Die Preview ist geschützt. Der Freigabelink ist für dich zum Ansehen.
Öffnen: https://kunde-website--k7m2q9xa.…/__gooddeploy/share#… (Freigabelink, 1 Tag gültig)
Preview: https://kunde-website--k7m2q9xa.…
Live schalten: gooddeploy promote k7m2q9xa
Für Kunden: gooddeploy share k7m2q9xa --days 7
Öffne den Link und klick die wichtigen Seiten durch: Startseite, Formulare, Login, Seiten mit Daten aus der Datenbank. Zur Kontrolle:
gooddeploy inspect k7m2q9xa # Status, Adressen, Namen der Variablen, Checks
gooddeploy logs k7m2q9xa # Laufzeit-Logs der Preview
gooddeploy logs k7m2q9xa --build # Build-Log
Ohne ID zeigt gooddeploy inspect das Live-Deployment, vor dem ersten promote das neueste, jeweils mit den Namen der Variablen je Umgebung. Bricht der Build ab, nennt gooddeploy Code und Grund; die häufigsten stehen unter Häufige Fehler.
Fehlt eine Variable, setze sie und deploye neu. Eine Laufzeit-Variable wirkt mit --apply sofort, ohne neuen Build:
gooddeploy env add API_URL --preview --apply
6. Kunden abnehmen lassen
Für die Abnahme bekommt dein Kunde einen eigenen Link, ohne Konto und ohne Passwort:
gooddeploy share k7m2q9xa --days 7
Der Link gilt 1 bis 30 Tage (Standard 7). Alle Links des Projekts widerrufst du mit gooddeploy share revoke. Mehr unter Freigabelink.
7. Live schalten
Gefällt der Stand, schalte genau dieses Deployment live, ohne Neubau:
gooddeploy promote k7m2q9xa
gooddeploy zeigt vorher, was live geht, und fragt nach. Danach ist die App unter der Projekt-Adresse live (z. B. https://kunde-website.…, steht in der Ausgabe); deine Domain zeigt bis Schritt 8 weiter auf Vercel. Nach dem Umschalten prüft gooddeploy die neue Version noch eine Weile und schaltet bei Fehlern von selbst zurück. Abwarten kannst du das mit gooddeploy promote k7m2q9xa --wait.
Stimmt etwas nicht, geht es in Sekunden zurück:
gooddeploy rollback
rollback tauscht nur den Code, nie die Daten. Hast du Migrationen eingespielt, muss die ältere Version mit dem neuen Schema zurechtkommen. gooddeploy status zeigt, was live ist und wohin rollback zurückschaltet. Alles dazu: Deploy, Preview, Promote, Rollback.
Hast du die Daten erst nach dem ersten promote eingespielt (Weg A), prüf die Live-Seite danach noch einmal.
8. Eigene Domain
Eigene Domains richtet in der Pilotphase goodDEV für dich ein; selbst per CLI kommt später. So läuft es:
- Schreib uns, welche Domains zum Projekt gehören (z. B.
kunde.deundwww.kunde.de) und welche die Hauptdomain sein soll. Die anderen leiten mit301auf sie weiter. - Senke bei deinem Domain-Anbieter einen Tag vorher die TTL der betroffenen Einträge (z. B. auf 300 Sekunden), dann geht die Umstellung schneller und ein Rückweg auch.
- goodDEV trägt die Domains ein und nennt dir die DNS-Einträge, die du beim Domain-Anbieter deines Kunden setzt. Erst damit zeigt die Domain auf gooddeploy.
- Prüfe die Seite unter der Domain im Browser, mit
https://.gooddeploy statuszeigt die Domains des Projekts.
Hat dein Kunde die Domain bei Vercel registriert oder nutzt er die DNS-Server von Vercel, kläre vorher, wo die Einträge künftig gepflegt werden. E-Mail-Einträge (MX, SPF, DKIM) der Domain bleiben, wie sie sind; nimm sie bei einem Umzug der DNS-Verwaltung mit.
Die Projekt-Adresse bei gooddeploy bleibt erreichbar, sendet aber noindex, damit Suchmaschinen nur deine Domain führen (siehe Eigene Domains).
9. Vercel abschalten
Schalte das Vercel-Projekt erst ab, wenn die Seite unter der eigenen Domain von gooddeploy kommt und eine Weile ohne Fehler läuft. Bis dahin ist der Weg zurück offen: DNS-Einträge zurück auf Vercel.
Vor dem Abschalten:
- Die Domain zeigt überall auf gooddeploy (auch für
wwwund weitere Domains), und die alte TTL ist abgelaufen. gooddeploy logs --since 1hzeigt keine unerwarteten Fehler.- Daten, die nach dem Dump bei Vercel noch geschrieben wurden, sind übernommen.
- Vercel-eigene Dienste (Blob, Cron, Analytics) sind ersetzt oder bewusst weggefallen.
- Webhooks und Rückruf-Adressen bei anderen Diensten (Zahlung, Login, Formulare) zeigen auf die neue Domain bzw. funktionieren damit.
- Eine aktuelle Sicherung liegt bei dir:
gooddeploy db dump -o nach-umzug.dump(Weg A) oder beim bisherigen Anbieter (Weg B).
Danach im Vercel-Projekt die Domain entfernen und das Projekt löschen oder pausieren. Nutzt du bei Vercel eine Datenbank aus dem Marketplace und bist mit Weg A umgezogen, kündige sie beim jeweiligen Anbieter erst nach deiner letzten Sicherung.
Was es noch nicht gibt
gooddeploy ist in der Pilotphase. Für den Umzug wichtig, und laut Plan für den Pilot vorgesehen (kommt später, ohne festen Termin):
- Vorschau bei jedem Push aus GitHub und live per Merge. Heute deployst du per Befehl, auch aus deiner CI (siehe Skripte und CI).
- Dashboard im Browser mit Deployments und Logs. Heute läuft alles über die CLI.
- Cron-Jobs aus
vercel.json. Bis dahin ruft z. B. deine CI oder ein anderer Dienst den Pfad im Takt auf. - Eigene Domains selbst einrichten (
domains add). Heute richtet goodDEV sie ein. - Migrationen einmal je Live-Schalten (
release-Befehl). Heute über eine eigene Startdatei (siehe Migrationen ausrollen). - Sicherung selbst einspielen bzw. Daten direkt aus der alten Datenbank übernehmen, und automatische Backups der Datenbanken. Heute hilft goodDEV.
- Externe Datenbank per Befehl anbinden (z. B. Neon oder Supabase). Heute mit
gooddeploy env add DATABASE_URL.
Nicht geplant sind ein Ersatz für Vercel Blob, Global Config und Web Analytics sowie Edge Functions an weltweiten Standorten.
Checkliste
Zum Abhaken, je Projekt:
- Zugang von goodDEV, CLI installiert,
gooddeploy loginundwhoamiok - Vercel-eigene Dienste (Blob, Cron, Analytics, Global Config) aufgelistet und Ersatz geklärt
next buildundnext startlaufen lokal, alles committet, Lockfile dabeioutput: "standalone"gesetzt, oder ohnestandalonemit eigenerserver.js, wenn Migrationen beim Start laufen sollen.gooddeployignorefür große Dateien committetredirectsaus dervercel.jsonin dienext.configbzw. diegooddeploy.jsonübernommen- Datenbank entschieden: Postgres bei gooddeploy oder bisherige behalten
gooddeploy link <projekt>(mit oder ohne Postgres)- Variablen je Umgebung mit
vercel env pull --environment=…undgooddeploy env importübernommen, Dateien gelöscht - Secret-Werte, mehrzeilige Werte und ggf.
DATABASE_URLeinzeln gesetzt,gooddeploy env lsgeprüft NEXT_PUBLIC_…in Previews und Live gleich- Daten übernommen (Dump an goodDEV) oder externe Datenbank verbunden
gooddeploy deploy, Preview durchgeklickt,inspectundlogsohne Fehler- Kunde hat über
gooddeploy share <id> --days 7abgenommen gooddeploy promote <id>, Live-Adresse geprüft,rollbackbekannt- TTL gesenkt, Domains an goodDEV gemeldet, DNS-Einträge gesetzt, Seite unter der Domain mit HTTPS geprüft
- Webhooks und Rückruf-Adressen angepasst, letzte Sicherung gezogen
- Vercel-Projekt abgeschaltet
Quellen zu Vercel
Angaben zur Vercel-CLI aus der Doku von Vercel, abgerufen am 22.10.2026: vercel env (https://vercel.com/docs/cli/env) und Config- und Secret-Variablen (https://vercel.com/docs/environment-variables/sensitive-environment-variables). Vercel ist eine Marke der Vercel Inc.