Docs menu

Moving an app from Render

A walkthrough for moving a running Render app to Primcloud with zero downtime.

On this page

Before you start#

You'll need a Primcloud account with GitHub connected (the Quickstart walks you through it) and access to your services in the Render Dashboard, so you can read their commands and environment variables.

A few things go by different names here:

On Render On Primcloud
Web service, background worker Pod formation
Instance count Instances
Compute plan Compute size
Start command A line in your Procfile
Pre-deploy command The release line
Cron job A scheduler process
Environment variables Secrets
Shell and render ssh Tasks
*.onrender.com *.primcloud.app

The guide follows one app, hack-the-planet, from start to finish: a web service, a worker service and a nightly cron job.

1. Write a Procfile from your services#

Primcloud doesn't read render.yaml. Each service becomes a line in a Procfile at the root of your repo, using its start command, and the web service's pre-deploy command becomes the release line. If you don't use a Blueprint, each service's Settings page shows the same commands.

render.yaml
services:
  - type: web
    name: hack-the-planet
    runtime: docker
    preDeployCommand: perl bin/release.pl
    dockerCommand: perl bin/board.pl
  - type: worker
    name: hack-the-planet-queue
    runtime: docker
    dockerCommand: ./bin/queued -d
Procfile
release: perl bin/release.pl
web: perl bin/board.pl --port=$PORT
worker: ./bin/queued -d

Only the web line gets HTTP traffic, on the port in $PORT. Render sets PORT to 10000 unless you changed it, so if your app listens on 10000 directly, make it read $PORT.

A build command you set on Render doesn't carry over. The Customizing the build page for your language under Language Support shows where build steps go.

Note

On Standard, a service on Render's Docker runtime builds from your repo's language files here. Pro and Team can build from a Dockerfile, as Plans shows.

2. Give your cron job a scheduler#

Primcloud has no cron schedule, so a cron job becomes a process that stays up and starts the job on time.

The hack-the-planet-cleanup cron job runs perl bin/garbage.pl --purge at 0 3 * * *. Write a small bin/scheduler.pl with your language's cron library that runs the same command on the same schedule:

Procfile
release: perl bin/release.pl
web: perl bin/board.pl --port=$PORT
worker: ./bin/queued -d
scheduler: perl bin/scheduler.pl

Render's schedules are UTC, so run your scheduler in UTC too.

Important

Every instance of scheduler runs every job. Keep it at one instance when you turn it on in step 5.

3. Pull up your environment variables#

Open each service's Environment page in the Render Dashboard, along with any environment group linked to it. Every process shares one set of secrets here, so a variable both services use goes in once.

Leave PORT out, since Primcloud sets it for you. If you set a version variable like PYTHON_VERSION or NODE_VERSION on Render, leave it out too: Primcloud reads the version from your repo, as the Runtime versions page for your language under Language Support shows. Leave Render's own RENDER_* variables out too, since Primcloud doesn't set or read them. If your code reads one, like RENDER_EXTERNAL_URL, switch it to one of the variables Primcloud sets.

Warning

Primcloud has no secret files, and a secret's value is a single line, so a multi-line file from /etc/secrets/, like a PEM key, can't be pasted in as it is. Put it on one line with base64 < signing-key.pem | tr -d '\n', add the result as a secret, and have your app decode it when it starts.

4. Import your repo#

From your applications list, hit Import Git Repository. Pick the repo, then on the Configure step choose your branch and region.

That Configure step also has a Secrets list. Add your environment variables there and they're saved before the first build.

The Secrets list with paired key/value rows, one value revealed and the rest masked, per-row remove buttons, Add More, and Save

Check the commit and hit Import. The first deploy starts right away.

A deployment's detail page with its Build and Rollout phases both complete, the Build phase expanded to its log

Once Rollout shows Complete, open your app at hack-the-planet-production.primcloud.app. Forgot a secret? Add it under Settings → Secrets and save. Once your app is running, saving redeploys it with the new value, no rebuild needed. If the first deploy failed, save the secret, then hit Redeploy on that deployment.

Warning

Pods don't keep files between restarts or deploys. If your app writes to a Render persistent disk, move that data into an object store before you move your domain.

5. Turn your workers on#

Important

After the first deploy, only web is running. Every other process starts at 0 instances, so worker and scheduler are off until you scale them up.

Open Pod Formations on your app's dashboard and expand a formation. Instances is your instance count. Formation Size is your compute plan: the memory and CPU each instance gets.

The Pod Formations panel with web expanded at 2 instances on Standard 2x, showing the Formation Size selector and the Instances slider, and worker below it at 1 instance on Standard 1x

Everything starts on Standard 1x, our smallest size. Memory is a hard limit, so pick a size with at least as much memory as your compute plan has on Render. Scaling formations has the details.

6. Swap the Render shell for tasks#

Anything you'd run from a service's Shell page or with render ssh becomes a task. It runs your command on a fresh instance of your current build, with the same secrets as your app, and streams the output while it runs.

A task run with the command across the top, a succeeded badge with its exit code, and the run's output below

A task isn't an interactive shell. Give it a command and it runs until that command exits.

7. Move your domain#

  1. Add your domain in your app's Settings. We'll show you the two DNS records to add, a CNAME and a TXT record.
  2. Add the TXT record at your DNS provider.
  3. Replace the record that points your domain at Render, a CNAME to your onrender.com subdomain or an A record, with the CNAME we showed you. For a root domain like example.com, use an ALIAS, ANAME or flattened CNAME; DNS setup explains why.
  4. Wait for the domain to show Success. We keep checking DNS for up to 72 hours, and once it verifies, your app is served over HTTPS.
  5. Make it your primary domain. Your primcloud.app URL then redirects to it.
A pending custom domain showing its status with the exact CNAME and TXT DNS records to add, each with a copy-to-clipboard button

Note

Render adds a domain's www and root versions together. Here each is its own domain, so add both and set the one that isn't primary to redirect, as Domains shows.

8. Switch Render off#

Delete your Render services:

Terminal
render services delete hack-the-planet --confirm
render services delete hack-the-planet-queue --confirm
render services delete hack-the-planet-cleanup --confirm