Migrate to Zenifra

This plan helps you move a production app from another platform to Zenifra with minimal downtime. The idea is simple: run everything in parallel, validate on the Zenifra URL, and only then switch DNS.

Seven-step plan

Take inventory

List every service in the current app: web processes, workers, scheduled tasks, databases, cache, environment variables, domains, and external integrations. Each process becomes a project on Zenifra.

Create the organization and invite the team

Create or pick an organization and invite the people involved with the permissions they need.

Create databases and managed services

Create the databases, cache, and queues before the app. That way the connection URLs already exist when you add the variables.

Deploy the app

Use your framework guide and the equivalents table below. Copy the environment variables from the current platform, replacing database and cache URLs with the new ones.

Copy the data

Follow Migrate the database. Do a full rehearsal before switch day to measure how long it takes.

Validate on the Zenifra URL

Test the app on *.clients.zenifra.com: sign-in, main flows, email sending, webhooks, and integrations.

Switch DNS

Lower the DNS record TTL to 300 seconds a day ahead. At the agreed time, freeze writes on the old platform, run the final data copy, configure the domain on Zenifra, and update DNS. Keep the old platform running for a few days for rollback.

Platform equivalents

HerokuZenifra
AppProject
web dyno in ProcfileProject start command
worker dynoAnother project from the same repository with a different start
release: in ProcfilePrefix in start, such as npm run migrate && npm start
Config VarsEnvironment variables
Heroku PostgresManaged PostgreSQL
Heroku RedisManaged cache or Key-Value
BuildpacksNode.js or Python runtime, or OCI Image for other languages
Review AppsPreview Environments
$PORTProject Port field. Set PORT as a variable if your code depends on it

Migrate the database

PostgreSQL

Export the current database in custom format and restore it on Zenifra with the console URI, which already enforces TLS:

pg_dump --format=custom --no-owner --no-acl "$OLD_URL" > dump.pgdump

pg_restore --no-owner --no-acl --jobs=4 \
  --dbname="postgresql://user:password@host:port/db?sslmode=verify-full&sslrootcert=system" \
  dump.pgdump

Use a pg_dump version equal to or newer than the source database. --no-owner avoids permission errors with users that do not exist on Zenifra.

MariaDB and MySQL

mysqldump --single-transaction --routines --triggers -h OLD_HOST -u USER -p DATABASE > dump.sql
mariadb --ssl -h ZENIFRA_HOST -P PORT -u USER -p DATABASE < dump.sql

Validation

Compare row counts of the main tables in both databases and run the app's smoke tests against the new database.

Files and uploads

Copy files from the current disk or bucket to the new destination before the switch. If you use persistent storage, a practical approach is to expose a temporary password-protected import endpoint and remove it afterwards.

Switch-day checklist

  • DNS TTL lowered in advance
  • App validated on the *.clients.zenifra.com URL
  • Variables reviewed, with no URLs from the old platform
  • External webhooks (payments, GitHub, email) updated to the new domain
  • Final data copy done and validated
  • Domain configured and HTTPS active
  • Old platform kept running for rollback

Need help migrating?

For larger migrations, email [email protected] with the inventory from step 1. See also the help center.

Next steps

Last updated on

On this page