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
| Render | Nodion |
|---|---|
| Web service | Application with the web process |
| Background worker | Another process of the app, such as worker |
| Private service | Process 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 site | Static sites buildpack |
| Build and start command | Buildpack detection and Procfile, or the process command |
| Pre-deploy command | Release command or Procfile release: entry |
| Render Postgres | Managed Postgres, attached as DATABASE_URL |
| Render Key Value | Valkey, attached as REDIS_URL |
| Persistent disk | Volume |
| Preview environments, service previews | Preview 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.