Migrate from Render to Dokku

A practical plan for moving Render web services, workers, cron jobs and Postgres to a Dokku server you control, with the work, risks and cutover steps made explicit.

On this page

How to migrate from Render to Dokku without losing data or downtime

Moving Render web services, workers and cron jobs to Dokku is feasible for single-server workloads, while Postgres and multi-service stacks take more planning. If a renewal, a rising bill or a need for data control has prompted this review, the decision rests on whether your apps fit one host and whether your team will run that host. Platform or DevOps engineers usually do the rebuild, often with an implementation partner for the database cutover, hardening and runbooks. Dokku runs on a single server by default and needs at least 1 GB of RAM for its default Docker scheduler, so you should size the machine against your heaviest service before you start. Render's managed autoscaling, its region choice and its HIPAA-eligible workspaces do not carry over automatically. You must either replace each one with infrastructure you operate or accept losing it, and that should be a written decision made before cutover, not after.

Start by inventorying every Render service, its type, its environment variables, its health checks and every attached Postgres instance, then decide how each one maps to Dokku. Web services map to the web process type in a Procfile, background workers map to other process types scaled with ps:scale, and scheduled jobs need an app.json cron entry or a host-level scheduler, because Dokku documents that not all Heroku app.json features are supported. Confirm each build path by running a test deploy with git push dokku, choosing among the herokuish builder, Cloud Native Buildpacks through the pack CLI, or a Dockerfile. Rebuilding with a Dockerfile is often the least surprising path for services whose Render build depends on system packages. Keep a record of each mismatch, since that list becomes your acceptance test for the cutover.

Which Render features map cleanly to Dokku and which need rework

This table maps each Render feature to its Dokku equivalent and marks it as clean, needs rework or gap. Read the status column first, then the notes, which name what you must rebuild or confirm in your own environment before cutover. Most app code moves directly, while Blueprints, cron setup, static sites and Key Value need the most planning.

Render featureDokku equivalentStatusNotes
Git push deploysgit push to a dokku remote, creating apps on the flyCleanReplace the Render Git connection with a push to your Dokku server. Update CI scripts and deploy hooks that assume Render.
Web services and background workersProcfile process types, with web scaled to 1 on first deploy and ps:scaleCleanEach Render service becomes a process type. Scaling is manual with ps:scale on one server, so Render autoscaling has no direct match.
Cron jobsapp.json cron tasks based on Heroku's formatNeeds reworkRecreate each Render cron job as a task and confirm its schedule and command. Dokku documents that not all Heroku app.json functionality is supported.
render.yaml BlueprintsNo direct Dokku file; split into Procfile, app.json and environment settingsNeeds reworkTranslate service, environment and disk settings by hand. Private networking and other Render-specific options need confirmation on your Dokku host.
Build methodDockerfile, Cloud Native Buildpacks via pack CLI, herokuish, Nixpacks or RailpackNeeds reworkChoose the builder explicitly and reproduce Render's runtime. Cloud Native Buildpacks need the pack CLI installed separately.
Render Postgresdokku-postgres plugin with postgres:export and postgres:importNeeds reworkDump the Render database and import it into the plugin. Linking sets DATABASE_URL, and the plugin installs PostgreSQL 18.6 by default.
Key Value (Redis-compatible)Dokku Redis pluginGapConfirm that the Redis plugin supports the commands, persistence and eviction settings your app uses before you plan the switch.
Static sitesNo static-site type in the supplied Dokku facts; serve the build output from a web processGapConfirm how your build output will be served, such as a Dockerfile with a static server, and how headers and redirects are preserved.
Custom domains, proxy and certificatesDefault nginx proxy, with Caddy, HAProxy, OpenResty or Traefik as alternativesNeeds reworkRepoint DNS and add domains to the app. Confirm certificate issuance and renewal in the Dokku proxy documentation before cutover.

What data and integrations move, and which export paths are documented

Moving from Render to Dokku is less a single export than four separate workstreams: the database, the configuration, the files and the external connections. Each one has a different owner and a different failure mode, so plan and verify them individually before the cutover.

Render Postgres dump path

Export the Render database with a logical backup or pg_dump, then load it into a Dokku Postgres service with the dokku-postgres plugin's postgres:import command. The plugin also offers postgres:export and scheduled backups to S3-compatible storage, which you can use on the Dokku side after restore. Confirm in Render's documentation which export formats and access methods your plan supports, and test a full restore against a copy before you rely on it.

Environment variables re-entered per app

Render stores environment values per service, and those values do not travel with a Git push. Set each one on the matching Dokku app, and confirm that linking the Postgres service sets DATABASE_URL correctly for each app. Review any value that a Render Blueprint generated automatically, since those do not appear as ordinary settings you can copy. Keep a secrets inventory so nothing is missed at cutover.

Uploaded files and object storage

Files stored on a Render persistent disk or in an external bucket do not move with the database dump. Identify every path the application writes to, copy those files to the Dokku host or to S3-compatible storage you control, and update the application's configuration to point at the new location. Confirm with Render's documentation how to export disk contents, because the database export does not cover them.

Webhooks, DNS records and callbacks

Third-party services that call your app, such as payment providers, login providers and Git hooks, hold the current Render hostname or IP settings. Update each webhook endpoint and OAuth redirect URI to the new domain, and change DNS records only after the new certificates are issued. Document every callback before cutover, because a missed one fails silently until a user reports it.

Cron jobs and scheduled tasks

Render cron jobs run as separate services, so they will not be restored from the database or the application image. Recreate each schedule as a Dokku app.json cron entry or an equivalent scheduled task, and confirm that the schedule runs once rather than on every replica. Check the schedule's dependency on environment variables and database access, which must match the new app.

The migration sequence from inventory to decommission

This sequence moves Render workloads to a Dokku host in stages, so each service and database is proven on the new platform before any traffic or data is switched. Every step ends with a written artifact that the team can review before moving on.

  1. Inventory every service, worker, cron job and database

    List each Render web service, background worker, cron job, static site and Postgres instance, and record for each its build method, start command, environment variables, custom domains, instance size, region and any attached disks. Note which Render Postgres instances are on plans with paid backups and which settings in the Render dashboard are not visible in source code. The output is a service inventory with one row per resource, plus an owner for each row. Confirm the inventory against the Render dashboard rather than against your repository alone, because repositories often omit settings made in the dashboard.

  2. Pilot one stateless web service on Dokku

    Choose one stateless web service with no database dependency and deploy it to a test Dokku host. Use a Procfile if the app already declares its web process, or a Dockerfile if the build depends on system packages. Dokku builds with herokuish, Cloud Native Buildpacks through the pack CLI, or a Dockerfile, so confirm which builder fits the app before pushing. Set environment variables with the config commands, then compare response behavior with the Render version. The output is a working pilot with a written list of gaps, such as missing build steps or runtime differences.

  3. Build the Dokku server and install plugins

    Install Dokku on a server you control, following the installation guide for your operating system and confirming it meets the documented version and memory requirements. Install the dokku-postgres plugin and any other datastore plugins the inventory calls for, and configure the proxy. Dokku ships nginx by default, and you can choose Caddy, HAProxy, OpenResty or Traefik instead, so record the choice and its reason. Add backups for Postgres to S3-compatible storage and test one restore. The output is a host build record covering OS version, Dokku version, plugin versions, proxy choice and backup configuration.

  4. Map process types, cron tasks and workers

    Translate each Render background worker and cron job into a Dokku process type or scheduled task. Declare workers in the Procfile, check how Dokku reads process formation under its procfile-util strict mode rules, and use app.json for cron tasks where the format supports them, noting that Dokku does not support every Heroku app.json feature. If a Render job runs as a separate service, scale its process type with ps:scale and confirm it does not start twice. The output is a process map that lists each Render service type beside its Dokku equivalent and the test that proves it runs.

  5. Restore a copy of Render Postgres and verify it

    Export each Render Postgres database using the export method your plan supports, then import it into the Dokku Postgres service with postgres:import. Run row counts, migration version checks and a sample of application queries against the restored copy, and compare them with the source. Record the restore log, the Dokku Postgres version, and any extensions that needed manual setup. The output is a restore verification log signed off by the application owner. Confirm the PostgreSQL version on both sides before you start, because major version differences affect how you move data.

  6. Run a parallel environment before cutover

    Run all migrated services on Dokku against the restored database copy while Render stays live, and send test traffic or replayed requests to the Dokku endpoints. Check logs, error rates, background job completion, cron timing and outbound email or webhook behavior. Keep a written rollback plan that names the DNS record to revert, the Render service to re-enable and the point at which the team reverts. The output is a parallel run report and an approved go or no-go decision from the service owner.

  7. Cut over DNS and certificates

    Lower the TTL on the affected DNS records ahead of the change, then point each custom domain at the Dokku host. Confirm that the proxy issues valid certificates for every domain and that HTTP redirects to HTTPS. Freeze writes to the Render database, take a final export and import it, then switch the application to the Dokku database connection. Keep Render running in read-only mode until the post-cutover checks pass. The output is a cutover log with the time of each DNS change, certificate status for each domain and the results of smoke tests.

  8. Decommission Render after the retention period

    Keep the Render services and database available for a retention period your organization sets, so you can roll back and recover any data you did not yet copy. Confirm with your compliance and data owners how long backups must be kept and where the final export is stored. When the retention period ends, delete the Render resources, revoke associated tokens and remove the Render environment variables from your secret store. The output is a decommission record that lists each deleted resource, the final backup location and the date each resource was removed.

How the Dokku build, process and proxy path works after the move

A Render service becomes a Dokku app through one path: a git push to the dokku remote triggers a build, the builder produces a container image, the docker-local scheduler starts it on the Dokku host, and the proxy routes the app's domain to it. Dokku selects the builder from the files in the repository and from configuration. Its options are herokuish, which uses the v2a buildpack specification, Cloud Native Buildpacks through the pack CLI (which you install separately), a Dockerfile, and the Nixpacks and Railpack builders selected by nixpacks.toml or railpack.json. Your first task is to pick one per service and confirm it in a staging app, since a Render service that built from a Dockerfile should stay on the Dockerfile builder, and a buildpack-built service needs its Procfile and runtime version checked under the new builder. The Dokku builder documentation explains how the builder is set per app.

Dokku's default proxy is nginx, and Caddy, HAProxy, OpenResty and Traefik are the documented alternatives. The proxy maps each domain to the container's port and handles HTTPS, so the domain and certificate cutover in this migration happens at the proxy layer. Confirm which proxy the server runs before you point DNS at it, check the TLS certificate issuance for each domain, and keep the Render domains active until the Dokku app answers correctly. Because the docker-local scheduler runs containers directly on the one Dokku host, a host reboot, disk failure, or failed deploy affects every app on that server at once. Render's managed scaling spreads instances and restarts them for you, so on Dokku you must plan capacity, monitoring, restart behavior and backups yourself.

The k3s scheduler, added in Dokku 0.33.0, can build a multi-server K3s cluster, but it requires a Docker registry for the images it deploys, and only the initial Dokku server is configured as the git push target. If you expect to add servers later, decide now whether you need a registry and how the cluster will be operated, because switching schedulers later is a larger change than choosing the right one at the start. Before you commit to any multi-server design, confirm with the Dokku K3s documentation which features your chosen version supports, and document which server operators must use for deploys.

What drives the cost and duration of the move

This table lists the cost components of moving Render services, workers, cron jobs and Postgres to a Dokku server, who pays for each, and whether it is one-time or recurring. Use it to see which inputs move the total and to build the list of items to request in a written quote.

Cost componentWho pays or does the workOne-time or recurringWhat drives it up or down
Rebuilding services and configurationYour engineers or a contracted implementerOne-timeNumber of services, Dockerfile or buildpack fit, and how many environment values must be re-entered by hand
Mapping process types and cron jobsYour engineers, with testing timeOne-timeCount of worker and cron definitions, and whether Procfile and app.json cover them or need custom scripts
Postgres export and importYour engineers, plus the database downtime windowOne-timeDatabase size, write volume during cutover, and how much downtime the business tolerates
Migration tests and restore verificationYour engineers or QA, plus the time to confirm restores workOne-timeNumber of restores you verify, whether you test a full restore into a scratch server, and sign-off steps
Dokku server and storageYour organization, through your cloud or data center accountRecurringInstance size driven by RAM and app load, disk for images and databases, and region choice
Off-server backup storageYour organization, through your object storage accountRecurringRetention period, backup frequency, and size of the Postgres dumps sent to S3-compatible storage
Patching, upgrades and monitoringYour platform or ops teamRecurringFrequency of Dokku, Docker, OS and PostgreSQL minor updates, plus the monitoring stack you run
On-call and incident responseYour operations staffRecurringSingle-server scope means one host failure affects all apps, so recovery time and staffing hours depend on your objectives

What usually goes wrong when moving Render to Dokku

Most failed Render to Dokku moves trace back to a few assumptions made during the rebuild: that configuration carries over unchanged, that data restores completely, and that the old platform can be switched off before the new one is proven. The cards below cover six risks in the order they usually appear, each with a check to run before cutover.

Assuming render.yaml translates automatically

A Render Blueprint does not become a Dokku deployment on its own. Dokku reads a Procfile for process types and an app.json manifest for deploy scripts, cron tasks, formation and healthchecks, and its documentation notes that not all Heroku functionality is supported. Inventory every service, worker, cron job and disk in render.yaml, then map each one to a Procfile entry, an app.json field or a plugin, and mark anything with no equivalent as a manual task.

Missing environment variables

Render keeps environment values in the service dashboard or Blueprint, and a deploy that succeeds can still fail at runtime when a key is absent. Export the full list per service and per environment group, including secrets, and set them with dokku config:set before the first deploy. Confirm that linked Postgres sets DATABASE_URL as expected and that any Render-specific variables, such as ones referencing internal hostnames, are replaced.

Postgres restores that omit extensions or roles

A plain data dump restored into the dokku-postgres plugin can lose extensions, roles, ownership and grants that the application depends on. Before the cutover restore, list extensions and roles on the Render database, recreate them in the Dokku database, and compare object counts after the import. Restore into a test app first and run the application's read queries against it, because a missing extension often fails only on specific code paths.

Cron jobs that run twice during the parallel run

During a parallel run both platforms can execute the same scheduled job, which can send duplicate emails, charge twice or write conflicting records. Disable each Render cron job before enabling its Dokku counterpart, and document the order of changes for each job. Where the job is not idempotent, add a lock or a run marker in the database so a second copy exits immediately.

Certificates not issued before DNS cutover

Dokku routes domains through its proxy, which is nginx by default, and certificates depend on the domain resolving to the new server. If DNS moves before the certificate is issued, browsers see errors and the cutover looks failed even when the app is healthy. Add each custom domain to the Dokku app while DNS still points at Render, confirm the certificate issues against a test hostname, and lower the record TTL well before the change window.

No tested rollback

A rollback plan that only says to point DNS back at Render fails if the database has accepted writes on Dokku in the meantime. Decide in advance which system is the write source after cutover, keep the Render database for a defined period, and rehearse the reverse path with a restore from the latest Dokku backup. Confirm backup storage and retention for the dokku-postgres plugin before relying on it.

How the move differs by starting point and team size

A single web service with one small Postgres database is the simplest case for Dokku. The app builds from a Procfile and buildpack or a Dockerfile, the database is a Dokku plugin service, and the whole footprint can sit on one host. The main risks are small in scope, but they are still real: the database backup, the domain cutover and the secrets you re-enter.

  • Parallel run: Keep Render running until the Dokku copy has served traffic with the restored data and you have tested login, email and any webhooks.
  • Backup design: Use the dokku-postgres plugin to take scheduled backups to S3-compatible storage, and test a restore on a second server before you retire the Render database.
  • Ownership: You now own OS patching, Dokku upgrades, certificate renewal and uptime monitoring. Assign those tasks to a named person before cutover.
  • Single-server fit: A single host usually suits this case, but confirm that one machine's memory and disk cover the app and the database with headroom.
  • Rollback: Retain the previous image and the Render service until you have verified the new one, knowing a rollback will not restore database content.

Before cutover, confirm the Render database's export format and size with your own environment, and rehearse the full restore once.

Questions teams ask before moving from Render to Dokku

How much effort and cost does moving from Render to Dokku involve?

The main cost is staff time, plus the server and backup storage you pay for directly. Dokku itself is MIT licensed, so there is no per-instance platform fee, but Render's per-service and per-database charges stop only when you cut over and cancel them. Effort rises with the number of services, the number of datastores, how many build steps depend on Render-specific settings, and how much traffic must move with minimal downtime. Ask for a quote that lists each service, worker, cron job and database separately, plus backup and monitoring setup, so the one-time migration work is distinct from the recurring server, backup and upkeep costs.

How long does a Render to Dokku migration take?

The timeline depends on how many workloads you move, how standard their builds are, and how much data you migrate. Simple apps built with a standard buildpack or Dockerfile move quickly, while apps that rely on Render blueprint features, private networking or large databases need more planning and testing. The database cutover window is often the longest fixed step, because it depends on data size and how much downtime your application can accept. Confirm the duration with a written scope rather than relying on general estimates, and ask for the sequence of cutover steps in the plan.

Can our team migrate from Render to Dokku without outside help?

Yes, a team with Linux server experience and some Docker familiarity can do the migration alone, and Dokku's documentation covers installation, deployment and plugins. The harder parts are sizing the server, setting up backups and restores, handling DNS and certificates, and testing failover behavior that Render previously handled for you. If your team has no one who runs production Linux hosts, an implementation partner can plan, build and document the setup, then hand it over. DeployOpen plans, implements, hardens, backs up, documents and supports self-hosted platforms in your infrastructure, under a fixed-scope agreement.

What skills and ongoing work does Dokku require from our staff?

Your staff will own the server, operating system patching, Dokku upgrades, backups, monitoring and incident response. Dokku's docs say it runs on a single server, supports Ubuntu 22.04, 24.04 and 26.04 and Debian 11 or later, and needs 1 GB of RAM for the default Docker scheduler, so the operating model is closer to running your own host than using a managed service. Engineers should be comfortable with git push deployments, Procfile and app.json configuration, and reading container logs. Plan for an on-call rotation and a written runbook before the first cutover.

Can Dokku replace Render Postgres backups and point-in-time recovery?

Dokku can cover logical backups and restores, but it does not give you Render's managed point-in-time recovery out of the box. The official dokku-postgres plugin installs PostgreSQL 18.6 by default, exports and imports databases, and runs scheduled backups to S3-compatible storage. Continuous archiving and point-in-time recovery require you to configure WAL archiving and restore procedures yourself, and PostgreSQL does not provide automatic failover on its own. Test restores on a separate machine, document recovery time, and confirm which recovery window your business requires before cutover.

How do domains and certificates switch from Render to Dokku?

You point DNS at the Dokku server and let the configured reverse proxy handle routing and HTTPS. Dokku ships nginx by default and documents Caddy, HAProxy, OpenResty and Traefik as alternatives, so confirm which proxy your team will run and how it issues certificates. Lower DNS record TTLs before the change, add each domain to the Dokku app, verify certificate issuance on the new server, and keep Render running until traffic and certificates check out. Keep the old Render service in place for a rollback window, then remove it after verification.

Does Dokku scale beyond a single server?

By default, Dokku is designed around one server, and its default docker-local scheduler runs containers directly on that host. Dokku also has a k3s scheduler, introduced in Dokku 0.33.0, that builds a multi-server K3s cluster, but it requires a Docker registry and only the initial Dokku server is configured as the git push target. If your workloads need automatic scaling, multi-region failover or high availability database clusters, confirm whether a single Dokku host or a Kubernetes-based setup matches your requirements before you commit to a design.

How do builds and process types change when moving off Render?

Most Render services map to Dokku process types declared in a Procfile, with cron tasks declared through app.json, but the build step changes. Dokku builds apps with the herokuish builder, Cloud Native Buildpacks through the pack CLI, a Dockerfile, or other builders, and it scales the web process to 1 on the first deploy. Use ps:scale to set worker counts, and check that environment variables and health checks match what Render previously ran. Not all Heroku functionality is supported in app.json, so review each manifest field before you rely on it.

Where to confirm the Dokku and PostgreSQL details

Confirm the Dokku side against the project's own documentation before you install anything. The installation guide at Dokku installation docs lists the supported operating systems and the memory requirement for the default Docker scheduler, which you should check against the server you plan to use. The application deployment page covers the git push workflow and builder selection, the process management page covers Procfile handling, the release process type and ps:scale, and the app.json reference describes which Heroku manifest features Dokku honors. Because the app.json documentation notes that not all Heroku functionality is supported, read it against your own cron and healthcheck definitions rather than assuming parity. The dokku-postgres plugin README is the place to confirm the default PostgreSQL version, the export and import commands, and how scheduled backups reach S3-compatible storage.

Confirm the PostgreSQL side against the PostgreSQL project's documentation, not against a blog summary. The upgrading documentation explains the dump-and-restore, pg_upgrade and logical replication options, and the versioning policy shows which major version your Render database runs and when it leaves support. Check the version in your Render dashboard first, then compare it with the support dates in the policy, since a move to a new host is a convenient point to pick a supported version. The continuous archiving page is the reference for point-in-time recovery, which Dokku's plugin backups do not replace on their own. Ask whoever owns the Render account to confirm the export settings, the backup retention on your plan, the environment variables and the custom domains in the Render dashboard, because those values live in your account and no public document can confirm them for you.

Record what each source confirmed, with the date and the version you checked, in the migration runbook. Dokku and plugin releases change, and a runbook that cites a version you did not verify will mislead the next person on call. Before cutover, run a restore of a recent Render export into a staging Dokku app and confirm the row counts and application behavior, then repeat the check on the production date. Where a documented behavior is unclear for your stack, such as a buildpack, an extension or a cron expression, test it in staging and write down the result. The sources give you the baseline, but the runbook should record what your environment actually does.

How DeployOpen scopes, runs and supports the Render to Dokku move

DeployOpen plans and implements the move from Render to a Dokku server inside your own cloud account, data center or air-gapped network, using a written scope agreed before work starts. Engagements are fixed-scope, and ongoing support, upgrades and continuous testing are available as retainers.

How we scope

  • Inventory every Render web service, background worker, cron job, static site and Postgres instance, with its plan and environment groups.
  • Confirm which buildpack or Dockerfile path each service uses and which Procfile process types it depends on.
  • Agree in writing the target server sizing, the Dokku version, the proxy choice and the cutover window before work begins.

How we build

  • Rebuild each service on Dokku with a Procfile, app.json or Dockerfile, and map Render cron jobs to Dokku scheduled tasks.
  • Migrate Render Postgres by logical dump and restore into the dokku-postgres plugin, then verify row counts and application behavior.
  • Configure domains, TLS certificates and the reverse proxy, and test each service in staging before pointing production traffic at it.

How we hand over

  • Document the server layout, app configuration, environment variable inventory, backup jobs and the restore steps you will run yourself.
  • Deliver a cutover runbook with the rollback path, including the note that a rollback does not restore databases or persistent files.
  • Walk your operations team through deploys, scaling with ps:scale, and database backups so ownership transfers cleanly.

How we support

  • Support is available as a retainer for Dokku and plugin upgrades, patching of the host operating system and backup verification.
  • Continuous security testing of the deployed applications and APIs can be scoped alongside the retainer if your team needs it.
  • Confirm with DeployOpen during scoping which support hours, response paths and upgrade windows apply to your engagement.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.