Migrate from Render

Move Render services with their Postgres, env vars and domains.

On Render every part of an application is its own service: web service, background worker, private service, cron job. On Nodion you build one image and run several processes from it in one application; cron jobs belong to the app. Nodion does not read a render.yaml, so you move the settings by hand.

What maps to what

RenderNodion
Web serviceApplication with the web process
Background workerAnother process of the app, such as worker
Private serviceProcess with a port, reachable internally at <app>-<process>.app.internal (also gets a public hostname, see step 3)
Cron job (its own service)Cron job on the app
Static siteStatic sites buildpack
Build and start commandBuildpack detection and Procfile, or the process command
Pre-deploy commandRelease command or Procfile release: entry
Render PostgresManaged Postgres, attached as DATABASE_URL
Render Key ValueValkey, attached as REDIS_URL
Persistent diskVolume
Preview environments, service previewsPreview environments

1. Create the project and the database

Create a project and, in it, a PostgreSQL database in the region the app should run in. The app and its database must be in the same region. Pick a Postgres version at least as new as on Render. More on Databases.

2. Copy the database

The external database URL is on the Render database's Info page; Render only accepts external connections with TLS (Render docs). Stop writes from your services, then create the dump as Render's backup docs show. -n public takes only the public schema; leave it out if your app uses other schemas.

bashpg_dump --dbname="RENDER_EXTERNAL_DATABASE_URL" -n public --no-owner \
  --format=directory --jobs=4 --compress=0 -f render.dump/

In Nodion, open the database's Overview tab and click Enable public access. Once the endpoint no longer shows Provisioning, copy the connection URL (always TLS) and add your own IP under Allowed sources. Then restore:

bashpg_restore --verbose --no-owner --no-privileges --jobs=4 --format=directory \
  --dbname="postgresql://nodion:PASSWORD@HOST:PORT/DATABASE?sslmode=require" \
  render.dump/

Use a pg_restore at least as new as the newer of the two servers. Check row counts on the Browse tab, then turn public access off again; the database keeps running internally.

3. Create the application and its processes

Create an application from the web service's Git repository. If Render built from a build and start command, use the Buildpacks strategy (Buildpacks); a Procfile sets the commands, otherwise the language defaults apply. If the service ran on Docker, use the Dockerfile strategy.

Render sets PORT to 10000 by default. Nodion sets PORT for the web process of buildpack apps (default 8080); if your app reads PORT, nothing changes. If 10000 is hard-coded, replace it. On Dockerfile apps Nodion sets no PORT; the app listens on the web process port.

Add every background worker from the same repo under Processes, New process as another process and enter its start command. A private service also becomes a process, with a port. Note: every process with a port gets a public default hostname next to its internal address; there is no private-only service. Protect such a port in the app (with authentication, for example). The Nodion hostnames can only be switched off for the whole app, once a custom domain is active. A worker that only consumes a queue needs no port. Move a pre-deploy command to a release: line in the Procfile (buildpacks) or to the app's release command (Settings, in the Preview environments card, where the field shows once previews are enabled, or release_command over the API). It runs once per deploy before web; if it fails, the previous release stays live.

4. Move the env vars

Render documents no dashboard export for env vars; the Render API returns a service's variables but not those from environment groups (Render API reference, GET /services/{serviceId}/env-vars; on environment groups see the Render docs). Collect them as KEY=value lines, including the values from environment groups, and paste them into Environment, Add many. Set secrets with nodion env set KEY=value --secret and values that span several lines through the CLI or API. Nodion has no secret files: store their content as a secret variable (--secret) and have the app read it from the variable or write the file itself at startup. Secrets do not belong in the image, as Render also warns.

Delete Render's DATABASE_URL and REDIS_URL again: a variable you set yourself overrides the value of an attached database. Attach the databases with Attach database. Inside Nodion the connection runs without TLS (sslmode=disable); if your code forces SSL, turn that off for this URL, and the same for rediss:// to Valkey.

5. Move the cron jobs

A Render cron job is its own service with a UTC schedule (Render docs). On Nodion you add it on the Cron tab of the app whose code it needs: a five-field schedule in UTC, the command, a timeout of up to 30 minutes, up to 8 jobs per app. While a run is still going, the next tick is skipped.

6. Deploy, move the domain, shut down Render

Deploy and check the Logs tab. Then add the domain on the Domains tab and set the two records Nodion shows: TXT _nodion-challenge.your-domain and a CNAME (an ALIAS at the apex) to the app's default hostname. Nodion offers no A record target, so at the apex your DNS provider needs ALIAS, ANAME or CNAME flattening. The certificate follows once the CNAME points at Nodion; expect a few minutes without a valid certificate and lower the TTL beforehand.

When everything runs, delete the Render services (Render CLI). Render keeps no backups of a deleted database, so keep your dump.

bashrender services delete my-service --confirm

Deleting the service does not delete the database or a Key Value instance. On paid instances Render persists Key Value to disk by default (Render docs): an empty Valkey is only enough for caches or queues you let drain first; if you need the keys, move them before you delete the instance. Delete the Render Postgres database yourself afterwards, with Delete Database at the bottom of its Info page (Render docs), and any Key Value instance as well; the CLI commands for both are in the Render CLI reference.

What works differently

  • There are no environment groups and no secret files; variables belong to one app each.
  • Workers and private services are processes of an app, not services of their own.
  • Cron jobs run on an existing app with its active release.
  • The CLI fetches logs but cannot follow them; watch them live on the Logs tab.

Next

Nodion compared with Render, Pricing, Applications and Databases.

Give your agent a cloud.

Earn up to 15 € in credit when signing up.

Continue with GitHub

or with email

Stay in the loop.

Product news, no spam. Unsubscribe anytime.