---
title: "Migrate from Render"
description: "Move a Render service to dply: import render.yaml, copy environment variables, replace Render databases and Key Value with dply resources, and switch the domain."
---

This guide is for web services, background workers, cron jobs and static sites on Render. dply reads your `render.yaml` on the first deploy, so the build and start commands, routes and headers come with you. Web services run as [container apps](/docs/containers); static sites are served from the edge.

## How the pieces map

| Render | dply |
|---|---|
| Web service | A container app |
| Static site | A static site ([Static & hybrid sites](/docs/static-and-hybrid)) |
| Background worker | **Queue workers** on the web app ([Queue workers](/docs/queue-workers)) |
| Cron job | A **Scheduled task** ([Scheduled tasks](/docs/scheduled-tasks)) |
| `render.yaml` | Imported on the first deploy (see below) |
| Build and start commands | **Build** settings; a `Procfile` also works ([Procfile](/docs/configuration-files#procfile)) |
| Pre-deploy command | The release command: `build.release` in `dply.yaml` or a `Procfile` `release:` line |
| Environment variables and groups | **Environment** ([Environment variables](/docs/environment-variables)) |
| Render Postgres | dply Postgres ([Postgres, MySQL & MongoDB](/docs/resources/databases)) |
| Render Key Value | dply Valkey ([Valkey (Redis)](/docs/resources/valkey)) |
| Persistent disk | Not available. Use [object storage](/docs/resources/object-storage) |
| Instance type and scaling | Instance size and instances ([Scaling & sleep](/docs/scaling-and-sleep)) |
| Pull request previews | [Preview deployments](/docs/preview-deployments) |
| `*.onrender.com` | The app's `*.on-dply.live` hostname ([Domains](/docs/domains)) |
| Rollbacks | **Roll back** ([Deployments](/docs/deployments#roll-back)) |
| Shell | The app's **Console** |

## What `render.yaml` import covers

When the repository has a `render.yaml` and no `dply.yaml`, dply takes the web service (the first `web` or `static` service) and uses its:

- `buildCommand` and `startCommand`, ahead of what dply would detect.
- `staticPublishPath` as the output directory.
- `routes` and `headers`, saved under **Routing** on the first deploy. After that the rules are yours to edit; the file isn't read for them again.

The create page and the first build log note what it didn't import:

- A `rootDir`: set the app's **Repository root** to it yourself.
- Other services: create each as its own app, or a worker service as queue workers.
- Databases: add one under **Add resource**.
- `envVars`: the create page lists their names; set the values under **Environment**.

See [Configuration files](/docs/configuration-files).

## 1. Deploy the app

1. Choose **New app**, connect your source control, and select the repository and branch.
2. Check the detected build and start commands, then choose **Deploy**.

## 2. Copy environment variables

In the Render dashboard, open the service's **Environment** and copy each variable, including those from environment groups. Paste them into **Environment** on dply as `KEY=value` lines. Leave out `DATABASE_URL` and `REDIS_URL`: dply sets them from the resources you attach next.

## 3. Attach resources

On the app's **Overview**, choose **Add resource** and add a **Database** for Render Postgres and **dply Valkey** for Render Key Value. Redeploy so the app receives the new variables.

## 4. Move the database

1. Stop writes to the Render service.
2. Export with the external connection URL from Render:

   ```bash
   pg_dump --no-owner --no-acl -Fc "$RENDER_DATABASE_URL" > app.dump
   ```

3. Open the database from the app's **Overview**. Under **Export and import**, choose **Get upload command**, run it where `app.dump` is, then choose **Load it**.

For MySQL, upload isn't available: restore with `mysql` using the **Connection URL** under **Connect**. See [Postgres, MySQL & MongoDB](/docs/resources/databases#export-and-import).

## 5. Switch the domain

1. Check the app on its `on-dply.live` address.
2. Add the domain under **Routing**, **Domains**.
3. Lower the TTL on the existing record, then point it at the CNAME target dply shows.
4. Choose **Verify DNS** and wait for TLS to be active.
5. Remove the custom domain from Render, then suspend the service.

See [Domains](/docs/domains).

## Next steps

- [Container apps](/docs/containers)
- [Scaling & sleep](/docs/scaling-and-sleep)
- [Troubleshooting builds](/docs/guides/troubleshooting-builds)
