Migrar desde Heroku

Migra una app de Heroku con su base de datos, sus config vars y su dominio.

Esta guía migra una app de Heroku a Nodion: código, config vars, Heroku Postgres, Heroku Key-Value Store, jobs del Scheduler y el dominio personalizado. Cuenta con una breve pausa de escrituras mientras se copia la base de datos. No hay importador para app.json ni heroku.yml; cada paso se resuelve con unos pocos clics o comandos.

Equivalencias entre Heroku y Nodion

HerokuNodion
AppApplication
Process types y dynos (web, worker)Procesos de una app, cada uno con sus propias réplicas y su propio paquete
Tamaño del dynoPaquete (Discovery, General Purpose)
Config varsVariables de entorno (pestaña Environment)
ProcfileProcfile (builds con buildpacks)
Release phaseEntrada release: del Procfile o el release command de la app
Heroku PostgresPostgres gestionado, vinculado como DATABASE_URL
Heroku Key-Value StoreValkey, vinculado como REDIS_URL
Heroku SchedulerCron jobs de la app
Review appsEntornos de preview
Automated Certificate ManagementCertificados automáticos

1. Crea el proyecto y la base de datos

Crea un proyecto y, dentro de él, una base de datos PostgreSQL en la región en la que se ejecutará la app (EU Central para Fráncfort). La app y su base de datos tienen que estar en la misma región; Nodion no permite vincularlas entre regiones distintas. Elige una versión de Postgres igual o más reciente que la de tu base de datos de Heroku. Más información en Bases de datos.

2. Copia la base de datos

Primero detén todas las escrituras. Con el modo de mantenimiento de Heroku, los dynos de worker y los jobs del Scheduler siguen ejecutándose. Por eso, escala a cero cada tipo de proceso que escriba (no solo worker) y quita los jobs de Heroku Scheduler mientras dure la copia. Según Heroku, el modo de mantenimiento no está disponible para las apps Fir; en ellas, escala también web a cero o detén las escrituras en la propia app:

bashheroku maintenance:on --app example-app
heroku ps:scale worker=0 --app example-app   # every process type that writes

En Fir:

bashheroku ps:scale web=0 worker=0 --app example-app   # Fir: no maintenance mode

Después crea y descarga un backup. Heroku lo guarda como latest.dump en el formato custom de pg_dump (documentación de Heroku). Heroku recomienda PGBackups para bases de datos de hasta 20 GB; para las más grandes, ejecuta pg_dump directamente contra la URL que devuelve heroku pg:credentials:url (bases de datos classic) o heroku data:pg:credentials:url (bases de datos Advanced, documentación de Heroku).

bashheroku pg:backups:capture --app example-app
heroku pg:backups:download --app example-app

Las bases de datos Advanced no admiten PGBackups; para ellas, y para las de más de 20 GB, haz el dump directamente en el mismo formato custom, con la URL del comando de credenciales correspondiente. Según Heroku, las bases de datos Private y Shield no aceptan conexiones externas (y Shield no tiene PGBackups); para ellas, sigue el procedimiento que Heroku describe para Private Spaces.

bashpg_dump -Fc --no-acl --no-owner -f latest.dump \
  "postgres://USER:PASSWORD@HOST:5432/DATABASE?sslmode=require"

En Nodion, abre la pestaña Overview de la base de datos y haz clic en Enable public access. Espera a que el endpoint deje de mostrar Provisioning y copia la URL de conexión que muestra el dashboard (siempre con TLS, sslmode=require). Añade tu propia IP a las fuentes permitidas para que solo tú puedas conectarte. Después, restaura:

bashpg_restore --verbose --no-owner --no-acl \
  --dbname "postgresql://nodion:PASSWORD@HOST:PORT/DATABASE?sslmode=require" \
  latest.dump

Usa un pg_restore igual o más reciente que el más nuevo de los dos servidores. Si la restauración da errores sobre el esquema heroku_ext, créalo antes: CREATE SCHEMA heroku_ext; (es un consejo de la propia Heroku). Comprueba el número de filas en la pestaña Browse de la base de datos y luego vuelve a desactivar el acceso público; la base de datos sigue funcionando internamente.

Un Valkey vacío solo basta si tu app usa Key-Value Store como cache o como cola que has dejado vaciar antes. Si guarda datos que necesitas (sesiones o claves persistentes, por ejemplo), muévelos antes del apagado o conserva el origen hasta que ya no los necesites.

3. Crea la aplicación

Crea una aplicación desde tu repositorio Git con la estrategia Buildpacks. Los buildpacks leen tu Procfile: web es el proceso por defecto y las demás líneas se convierten en process types (Buildpacks). En Node.js, un script heroku-postbuild se ejecuta después de la build. Como en Heroku, el proceso web recibe la variable PORT.

Si el Procfile no tiene una línea web:, su primera línea pasa a ser la línea por defecto y se ejecuta en el proceso web de Nodion. Nodion comprueba ese proceso por HTTP antes de ponerlo en producción, así que un worker sin servidor HTTP no supera esa comprobación. Mantén una línea web: para el servidor HTTP de tu app.

Las líneas del Procfile no crean procesos. Para una línea worker:, abre Processes, New process, llámalo worker y deja el comando vacío; así ejecuta el process type del mismo nombre.

Una línea release: se ejecuta una vez en cada despliegue, antes de que arranque web. Si falla, el despliegue falla y la release anterior sigue sirviendo el tráfico. Si en Heroku hacías la build con heroku.yml, usa la estrategia Dockerfile: ahí no hay Procfile, así que configura el release command de la app (Settings, en la tarjeta Preview environments, donde el campo aparece una vez activadas las previews, o release_command a través de la API). Nodion no define PORT en las apps con Dockerfile; la app escucha en el puerto del proceso web (si no, en el del EXPOSE de la imagen; si no, en el 8080).

4. Traslada las config vars

Exporta las config vars en formato shell (Heroku CLI):

bashheroku config -s --app example-app > heroku.env

Pega las líneas en Environment, Add many, e impórtalas. Revisa el resultado: los valores con comillas o barras invertidas pueden necesitar una corrección a mano, y los valores de varias líneas (claves PEM, por ejemplo) se introducen con la CLI o la API. Las variables importadas no son secretas; define los secretos con nodion env set KEY=value --secret.

Después borra DATABASE_URL y REDIS_URL de las variables importadas: una variable que defines tú sobrescribe el valor que inyecta una base de datos vinculada. Usa Attach database para la base de datos Postgres (url como DATABASE_URL) y para Valkey (url como REDIS_URL).

Dentro de Nodion, la conexión va por la red privada sin TLS (sslmode=disable). Si tu código fuerza SSL para la base de datos, como exige Heroku, desactívalo para esta URL; lo mismo vale para rediss:// hacia Valkey.

5. Los jobs del Scheduler pasan a ser cron jobs

Añade cada job de Heroku Scheduler en la pestaña Cron de la app: una programación cron de cinco campos en UTC, el mismo comando y un timeout de hasta 30 minutos. Una app admite hasta 8 cron jobs; si una ejecución sigue en curso, se omite la siguiente.

6. Despliega y comprueba

Despliega, sigue la pestaña Logs y abre la app en su hostname de Nodion. Si / no responde rápido con un 2xx o un 3xx, define tu propia ruta de health check en Settings.

7. Traslada el dominio

Añade el dominio en la pestaña Domains. Nodion muestra dos registros: un registro TXT _nodion-challenge.your-domain y un CNAME (un ALIAS en el apex) que apunta al hostname por defecto de la app. Puedes añadir el registro TXT con antelación. El certificado se emite en cuanto el CNAME apunta a Nodion, así que cuenta con unos minutos sin certificado válido después del cambio, y baja el TTL antes.

8. Apaga Heroku

Cuando el tráfico y los datos ya estén en Nodion, elimina la app de Heroku. Según Heroku, esto no se puede deshacer, así que conserva latest.dump.

bashheroku apps:destroy --app example-app

Qué funciona de otra manera

  • No hay modo de mantenimiento ni pipelines con promoción entre apps.
  • En lugar de dynos de ejecución puntual, la pestaña Shell abre un terminal en un proceso en ejecución.
  • La CLI obtiene los logs, pero no puede seguirlos; para verlos en directo, usa la pestaña Logs.
  • Los entornos de preview no necesitan app.json; cada uno recibe una base de datos vacía.
  • Un rollback vuelve a desplegar una imagen anterior con las variables de entorno actuales.

Siguientes pasos

Comparativa de Nodion y Heroku, Precios, Aplicaciones y Bases de datos.

Dale a tu agente un cloud.

Hasta 15 € de crédito al registrarte.

Continuar con GitHub

o con tu email

Mantente al día.

Novedades del producto, sin spam. Puedes darte de baja cuando quieras.