Von Heroku migrieren
Eine Heroku-App mit Datenbank, Config Vars und Domain umziehen.
Diese Anleitung zieht eine Heroku-App zu Nodion um: Code, Config Vars, Heroku Postgres,
Heroku Key-Value Store, Scheduler-Jobs und die eigene Domain. Plane eine kurze Schreibpause ein,
während die Datenbank kopiert wird. Einen Import für app.json oder heroku.yml gibt es nicht;
jeder Schritt unten sind ein paar Klicks oder Befehle.
Was wozu wird
| Heroku | Nodion |
|---|---|
| App | Application |
Process Types und Dynos (web, worker) | Prozesse einer App, jeder mit eigenen Replicas und eigenem Paket |
| Dyno-Größe | Paket (Discovery, General Purpose) |
| Config Vars | Umgebungsvariablen (Tab Environment) |
| Procfile | Procfile (bei Buildpack-Builds) |
| Release Phase | Procfile-Eintrag release: oder der Release Command der App |
| Heroku Postgres | Managed Postgres, angehängt als DATABASE_URL |
| Heroku Key-Value Store | Valkey, angehängt als REDIS_URL |
| Heroku Scheduler | Cron Jobs der App |
| Review Apps | Preview-Environments |
| Automated Certificate Management | Automatische Zertifikate |
1. Projekt und Datenbank anlegen
Leg ein Projekt an und darin eine PostgreSQL-Datenbank in der Region, in der die App laufen soll (EU Central für Frankfurt). App und Datenbank müssen in derselben Region liegen, sonst lehnt Nodion das Anhängen ab. Wähl eine Postgres-Version, die mindestens so neu ist wie deine Heroku-Datenbank. Mehr unter Datenbanken.
2. Datenbank kopieren
Stopp zuerst alle Schreibzugriffe. Im Maintenance Mode von Heroku
laufen Worker-Dynos und Scheduler-Jobs weiter. Skalier deshalb jeden Process Type, der schreibt, auf null (nicht nur
worker) und entferne die Jobs im Heroku Scheduler für die Dauer der Kopie. Auf Fir-Apps gibt es laut Heroku keinen
Maintenance Mode; dort skalierst du auch web auf null oder stoppst die Schreibzugriffe in der App selbst:
bashheroku maintenance:on --app example-app
heroku ps:scale worker=0 --app example-app # every process type that writes Auf Fir:
bashheroku ps:scale web=0 worker=0 --app example-app # Fir: no maintenance mode
Dann ein Backup erstellen und herunterladen. Heroku schreibt es als latest.dump im
Custom-Format von pg_dump (Heroku-Doku).
Heroku empfiehlt PGBackups für Datenbanken bis 20 GB; bei größeren nimm pg_dump direkt mit der URL aus heroku pg:credentials:url (Classic-Datenbanken) oder
heroku data:pg:credentials:url (Advanced-Datenbanken, Heroku-Doku).
bashheroku pg:backups:capture --app example-app
heroku pg:backups:download --app example-app Advanced-Datenbanken unterstützen PGBackups nicht; für sie, und für Datenbanken über 20 GB, dumpst du direkt im selben Custom-Format, mit der URL aus dem passenden Credentials-Befehl. Private- und Shield-Datenbanken lassen laut Heroku keine externen Verbindungen zu (Shield auch kein PGBackups); folge für sie dem Weg, den Heroku für Private Spaces beschreibt.
bashpg_dump -Fc --no-acl --no-owner -f latest.dump \
"postgres://USER:PASSWORD@HOST:5432/DATABASE?sslmode=require"
Öffne in Nodion die Datenbank, Tab Overview, und klick bei Public access auf Enable public access.
Warte, bis der Endpoint nicht mehr Provisioning zeigt, und kopier dann die Connection URL, die das Dashboard anzeigt
(immer TLS, sslmode=require). Trag unter den erlaubten Quellen deine eigene IP ein, damit nur du dich verbinden kannst.
Dann einspielen:
bashpg_restore --verbose --no-owner --no-acl \
--dbname "postgresql://nodion:PASSWORD@HOST:PORT/DATABASE?sslmode=require" \
latest.dump
Nimm ein pg_restore, das mindestens so neu ist wie der neuere der beiden Server. Meldet der Restore
Fehler zum Schema heroku_ext, leg es vorher an: CREATE SCHEMA heroku_ext; (der Tipp stammt von Heroku).
Prüf Zeilenzahlen im Tab Browse der Datenbank und schalte den öffentlichen Zugang danach wieder ab; die Datenbank läuft intern weiter.
Ein leerer Valkey reicht nur, wenn deine App den Key-Value Store als Cache nutzt oder als Queue, die du vorher leerlaufen lässt. Liegen dort Daten, die du brauchst (etwa Sessions oder dauerhafte Keys), zieh sie vor dem Abschalten um oder behalte die Quelle, bis sie nicht mehr gebraucht werden.
3. Application anlegen
Leg eine Application aus deinem Git-Repository an, mit der Strategie Buildpacks. Die Buildpacks lesen dein
Procfile: web ist der Standardprozess, die anderen Zeilen werden Process Types
(Buildpacks). Bei Node.js läuft ein heroku-postbuild-Script nach dem Build.
Wie auf Heroku bekommt der web-Prozess die Variable PORT.
Fehlt im Procfile eine Zeile web:, wird die erste Zeile zum Standard und läuft im web-Prozess von
Nodion. Diesen Prozess prüft Nodion vor dem Livegang per HTTP; ein Worker ohne HTTP-Server besteht diese Prüfung nicht. Behalte deshalb
eine Zeile web: für den HTTP-Server deiner App.
Procfile-Zeilen legen keine Prozesse an. Für eine Zeile worker: öffnest du Processes, New process,
nennst ihn worker und lässt den Befehl leer; dann läuft der gleichnamige Process Type.
Eine Zeile release: läuft bei jedem Deploy einmal, bevor web startet. Schlägt sie fehl,
schlägt der Deploy fehl und das vorherige Release bedient weiter. Hast du auf Heroku mit heroku.yml
gebaut, nimm die Strategie Dockerfile: Dort gibt es kein Procfile, setz den Release Command der App
(Settings, Karte Preview environments, wo das Feld erscheint, sobald Previews aktiviert sind, oder release_command über die API). Bei Dockerfile-Apps setzt
Nodion kein PORT; die App lauscht auf dem Port des web-Prozesses (sonst dem
EXPOSE des Images, sonst 8080).
4. Config Vars übernehmen
Exportier die Config Vars im Shell-Format (Heroku CLI):
bashheroku config -s --app example-app > heroku.env
Füg die Zeilen unter Environment, Add many ein und importier sie. Prüf das Ergebnis: Werte mit
Anführungszeichen oder Backslashes musst du eventuell von Hand korrigieren, mehrzeilige Werte (etwa PEM-Keys)
setzt du per CLI oder API. Importierte Variablen sind nicht geheim; Secrets setzt du mit
nodion env set KEY=wert --secret.
Lösch danach DATABASE_URL und REDIS_URL aus den importierten Variablen: Eine selbst gesetzte
Variable überschreibt den Wert, den eine angehängte Datenbank einspielt. Häng dann über Attach database
die Postgres-Datenbank (url als DATABASE_URL) und Valkey (url als REDIS_URL) an.
Intern läuft die Verbindung über das private Netz ohne TLS (sslmode=disable). Erzwingt dein Code SSL
für die Datenbank, wie es auf Heroku nötig ist, schalte das für diese URL ab; dasselbe gilt für rediss:// zu Valkey.
5. Scheduler-Jobs als Cron Jobs
Leg jeden Job aus dem Heroku Scheduler im Tab Cron der App an: Zeitplan als Cron-Ausdruck mit fünf Feldern in UTC, derselbe Befehl, ein Timeout bis 30 Minuten. Pro App gehen bis zu 8 Cron Jobs; läuft ein Job noch, fällt der nächste Termin aus.
6. Deployen und prüfen
Deploye, verfolg den Tab Logs und öffne die App unter ihrem Nodion-Hostnamen. Antwortet / nicht schnell
mit 2xx oder 3xx, setz unter Settings einen eigenen Health-Check-Pfad.
7. Domain umziehen
Trag die Domain im Tab Domains ein. Nodion zeigt zwei Records: einen TXT-Record
_nodion-challenge.deine-domain und einen CNAME (am Apex ein ALIAS) auf den Standard-Hostnamen der App.
Den TXT-Record kannst du vorab setzen. Das Zertifikat wird ausgestellt, sobald der CNAME auf Nodion zeigt; rechne nach
dem Umschalten mit ein paar Minuten ohne gültiges Zertifikat und senk die TTL vorher.
8. Heroku abschalten
Wenn Traffic und Daten auf Nodion laufen, lösch die Heroku-App. Das lässt sich laut Heroku nicht rückgängig machen, behalte also
latest.dump.
bashheroku apps:destroy --app example-app Was anders ist
- Es gibt keinen Maintenance Mode und keine Pipelines mit Promotion zwischen Apps.
- Statt One-off-Dynos öffnet der Tab Shell ein Terminal in einem laufenden Prozess.
- Die CLI holt Logs, kann ihnen aber nicht folgen; live mitlesen kannst du im Tab Logs.
- Preview-Environments brauchen kein
app.json; jedes bekommt eine leere Datenbank. - Ein Rollback deployt ein früheres Image mit den aktuellen Umgebungsvariablen.
Weiter
Nodion und Heroku im Vergleich, Preise, Applications und Datenbanken.