Move ERPNext from Frappe Cloud to self-hosted without losing books or files
Leaving Frappe Cloud for your own servers is a restore of a complete offsite backup onto a self-hosted bench with matching app versions, followed by a DNS switch. The effort depends mostly on your customizations, your integrations and the cutover window you can accept, so a company with a plain ERPNext site and a long weekend will have a very different project from one with custom apps, bank feeds and payment connectors. Control, cost and compliance are the usual reasons to move, and each one changes what you need to verify. Self-hosting ERPNext is free according to the ERPNext pricing page, so the cost you take on is the infrastructure you run and the people who do the work, including the staff who will patch, back up and monitor the servers after go-live. No duration is given here because it follows from the written scope.
Start by inventorying what your Frappe Cloud site depends on beyond the ERPNext code. List every installed app and its exact version, every Server Script and integration, and every scheduled job. Confirm with Frappe Cloud which backup you will use before you commit to a date. Every Frappe Cloud backup contains a database backup, public files, private files and the site config, but only backups marked offsite can be downloaded from the dashboard, and offsite backups are available on plans of USD 25 and above. If your plan or backup history does not meet that, resolve it first, because a backup you cannot download is not a migration path. Check the backup documentation in the Frappe Cloud site backups guide for the current retention and download behavior on your plan.
Decide how you will prove the restored site matches the source before users return. Compare document counts, the trial balance and open subledger totals between the Frappe Cloud site and the restored copy, and keep the encryption key from the site config safe, since losing it can leave encrypted fields unreadable. Plan the DNS switch with a short lowered TTL and a written rollback that keeps Frappe Cloud available until the new site is signed off. Also confirm that Server Scripts are enabled on your self-hosted bench, because they are disabled by default from version 15, and that any LDAP or social login settings are reconfigured against your own identity provider.
What carries over from Frappe Cloud and what you rebuild
This table compares each part of a Frappe Cloud site with what you must provide on a self-hosted bench. Read the right-hand column as your rebuild list, since every row marks something the new host does not inherit automatically. The main takeaway is that the database and files move with the backup, while settings tied to the provider, your identity provider and your domain need deliberate work before cutover.
| Item | On Frappe Cloud | On your self-hosted bench |
|---|---|---|
| Database | Captured in each backup as a database backup, restored by the platform | Restored from the downloaded database backup onto a matching database service you run |
| Public and private files | Captured as separate public and private files backups in each backup set | Restored into the site's files folders, with private files kept private on the new host |
| Site config | Captured as a site config backup, managed through the dashboard | Review the restored site config and confirm keys such as encryption settings and database details match your server |
| Scheduled backups | Taken on the provider's schedule, with offsite copies on plans of USD 25 and above (Frappe Cloud backup documentation) | You must configure your own backup schedule, offsite storage and restore tests |
| Server Scripts | Public shared benches do not allow them | Disabled by default from version 15 until server_script_enabled is set; re-review each script before enabling |
| Social Login Key and LDAP settings | Configured on the site and tied to the provider's network and callback addresses | Must be reconfigured and retested against your own identity provider, including redirect addresses and certificates |
| Outbound email | Handled by the provider's mail setup | Set up your own email account, sender domain records and delivery tests on the new host |
| Custom domains and TLS certificates | Managed through the dashboard | Issued and renewed on your server or load balancer, with DNS switched at cutover |
Which backup files to download from Frappe Cloud before you leave
Every Frappe Cloud backup holds four parts: a database backup, a public files backup, a private files backup and a site config backup. Your self-hosted bench needs all four to rebuild the site, so the download is a set, not a single file. Only backups marked offsite can be downloaded from the dashboard. Offsite backups are available on plans of USD 25 and above, according to the Frappe Cloud site backups documentation. Confirm that your current plan qualifies before you plan the exit, because a site on a lower plan may not give you a downloadable copy at all.
Private files and site config matter as much as the database. Private files hold attachments that are not publicly accessible, such as invoices, scanned documents and imports that users uploaded privately, and a database restore without them leaves broken references. The site config file holds the database credentials and the encryption key that ERPNext uses to protect stored secrets, such as passwords for integrations and bank connections. If that key does not match the restored database, those encrypted fields will not decrypt. Keep the site config file from the same backup set as the database so the two stay consistent.
Choose the backup you will restore from only after you have checked it. Pick the most recent offsite backup that completes after your planned freeze of user activity, and confirm its date and that all four parts are present. Then ask Frappe in writing how long offsite backups are retained and whether older sets remain downloadable after you cancel, so you have a fallback if the restore fails. Store the downloaded files in a location your team controls and record their checksums before the cutover window opens.
Choosing the self-hosted target: manual bench, Docker or Kubernetes
The bench command line tool installs ERPNext directly on a Linux server. Your team builds the bench, the Python and Node environment, the database and Redis services, and the supervisor or systemd processes that keep workers and the scheduler running. This route gives the most direct control over the operating system and the Frappe and ERPNext versions, and it is the closest match to how Frappe Cloud runs benches internally, which makes it a natural fit when the team already administers Linux servers.
- Who operates it: Your Linux or platform administrators, who own the host, patching, firewall rules and TLS termination.
- What you maintain: The operating system, MariaDB or PostgreSQL configuration, Redis, backup jobs, bench updates and every app version pinned to the site.
- Upgrades: Each bench update and app update is a command you run and test yourself, in the order your runbook defines.
- Fit: Teams with strong Linux skills who want a single host they can inspect and tune directly.
Confirm with your Frappe or ERPNext partner which OS release and Python and Node versions the matching ERPNext version requires, and write the bench build into a repeatable script before the first restore.
Docker Compose runs ERPNext as a set of containers on one host, defined in a Compose file. The containers handle the application, database, cache and background processes, so the host needs Docker and not a hand-built Python environment. This route suits teams that already run containers and want the application image, its configuration and its versions to live in version control.
- Who operates it: Your platform or DevOps team, who manage the Docker host, the image registry and the Compose configuration.
- What you maintain: The host OS, Docker itself, the pinned image tags, volume backups, secrets and the database service that the Compose file defines.
- Upgrades: You change the image tag, pull the new image and run migrations, so the version history sits in your repository.
- Fit: Teams comfortable with container runtimes who need a reproducible single-host deployment without Kubernetes.
Check that the Compose setup you choose is built from the production services and not from the single-file demo, and confirm how volumes for site files and database data are backed up.
The frappe_docker repository provides production images and Compose files that split ERPNext into separate services: MariaDB, Redis, background workers, the scheduler, Socket.io and Nginx. Splitting these services lets you scale workers and isolate failures, but it also means more moving parts to monitor. This route is the base that a Kubernetes deployment usually starts from, so the same service layout carries over if you later move to a cluster.
- Who operates it: A platform team that can read service logs, adjust worker counts and manage a reverse proxy and certificates.
- What you maintain: Each service image and version, the MariaDB and Redis data volumes, worker and scheduler health, Nginx configuration and TLS certificates.
- Upgrades: Image tags move per service, so your runbook must confirm that workers, scheduler and web containers all run the same ERPNext version.
- Fit: Teams that expect growth in users, background jobs or sites and want the service boundaries from the start.
The single-file demo setup in frappe_docker is for short-lived evaluation only. Do not load the migrated books into it, because it is not designed to hold production data.
How to move ERPNext from Frappe Cloud to self-hosted step by step
This sequence takes an ERPNext site from Frappe Cloud to a self-hosted bench with matching versions, verified data and a controlled DNS cutover, with sign-off before the old site is retired.
Inventory apps, scripts and integrations
Before any backup is taken, list every installed app, its version, every custom field, client script, server script, print format, report, scheduled job and external integration on the Frappe Cloud site. The site owner and the ERPNext lead agree on this inventory in the written scope, and each item is marked as moving, rebuilding or retiring. Server Scripts need particular attention: from version 15 they are disabled by default on self-hosted benches and must be enabled with the server_script_enabled setting, and Frappe Cloud public shared benches do not allow them, so confirm whether the site depends on them before you plan the target. The step is complete when the inventory is signed by the business owner and the integration owners.
Confirm Frappe and ERPNext versions
Record the exact Frappe Framework and ERPNext versions running on the Frappe Cloud site and check them against Frappe's supported versions page. Frappe's policy ties warranty coverage to running a listed version with a matching Frappe Cloud support plan, so confirm with Frappe what support status applies once the site leaves the platform. The target bench must use the same major and minor versions as the source, and each app must match its source version. The output is a version manifest, owned by the platform engineer, that lists every app and version the new bench will install.
Download the offsite backup
Each Frappe Cloud backup contains a database backup, public files, private files and site config. Only backups marked offsite can be downloaded from the dashboard, and offsite backups require a plan of USD 25 and above according to Frappe's Cloud backup documentation, so confirm your plan before you rely on this path. Trigger a fresh offsite backup, download all four components, and store them in an encrypted location you control. Verify the file checksums and that the site config contains the encryption keys needed by stored credentials. The step is done when all four artifacts are on your storage and the checksums match the dashboard.
Provision the self-hosted bench
Build the target environment with bench or the Docker-based setup, installing Frappe and ERPNext at the versions recorded in the manifest and the same versions of every companion app. Configure MariaDB, Redis, workers, the scheduler, TLS and backups on infrastructure you control, and keep the new site on a test domain. The platform engineer owns this work. The step is complete when the bench starts cleanly, every app version matches the manifest, and the empty test site responds over HTTPS.
Restore database, files and site config
Restore the database, public files, private files and site config onto the test site, using the same app versions as the source. Run the migration step so the schema matches the installed apps, then confirm that background workers and the scheduler are running. Check that document naming, file attachments and stored credentials open correctly. The step is complete when the restore log shows no errors and a user can open a sample of invoices, stock entries and attachments.
Verify counts, jobs and integrations on the test domain
Compare document counts for the key DocTypes, such as customers, suppliers, items, sales invoices, journal entries and stock ledger entries, between the Frappe Cloud site and the restored site. Confirm that scheduled jobs are enabled, that email and print work, and that every integration in the inventory is reconnected or pointed at the test endpoint, with outbound calls to live partners held back until cutover. Record each check with its result and an owner. The step is done when the finance and operations leads sign off the counts and the integration checklist.
Run a parallel period and reconcile both sites
Keep the Frappe Cloud site live and the self-hosted site running for a period agreed in the written scope, entering or replaying the same transactions in both where the business requires it. Compare reports, ledgers and open balances between them and investigate every difference until its cause is known. This is where most of the migration risk is controlled, because defects in scripts, permissions, number series and integrations usually appear under real use rather than in a restore. The step is complete when the differences are explained and the business owner accepts the parallel results in writing.
Freeze writes, take the final backup and switch DNS
Announce a write freeze on the Frappe Cloud site, stop integrations that write into it, and take a final offsite backup. Restore only the delta since the earlier backup onto the self-hosted site, then rerun the count and balance checks. Once they pass, change the DNS record to the new server, confirm that the new site serves traffic and that the scheduler and integrations run there, and keep the Frappe Cloud site in read-only state. The cutover owner records the time of the freeze, the backup identifier and the DNS change in the change log.
Decommission Frappe Cloud after sign-off
Keep the Frappe Cloud site in read-only state and retain its backups for the retention period your records policy requires, while monitoring the new site for errors in logs, scheduled jobs and integrations. Decommission the Frappe Cloud site only after the business owner, finance lead and security owner sign off in writing, and after you have stored the final backup in your own archive. The step is complete when the sign-off record, the archive location and the cancellation confirmation are filed together.
Documented restore and import paths for a Frappe Cloud exit
A Frappe Cloud exit combines one full restore with several follow-up fixes. The cards below separate the path that rebuilds the site from the paths that correct records and settings once it is running, so you know which steps are required and which apply only to specific gaps.
Download offsite backups from the dashboard
This is the starting point for a full restore. Each Frappe Cloud backup contains a database backup, public files, private files and site config, but only backups marked offsite can be downloaded from the dashboard. Offsite backups are available on plans of USD 25 and above, so confirm your current plan before you plan the exit. Download all four components from the same backup, record its timestamp, and store a checksum with each file so the restore set can be verified later. Confirm the backup is recent enough for your cutover window.
Restore onto a bench
Use this path for a full restore onto a self-managed bench with the bench command line tool. Match the Frappe Framework and ERPNext versions to the site on Frappe Cloud, install the same custom apps, then restore the database and files into a new site. Keep the site config so the encryption key and database settings carry over. Only the full restore path applies here, and you should run it against a staging host before cutover.
Restore onto frappe_docker images
Use this path for a full restore if you prefer containers. The frappe_docker repository provides production images and Compose services for MariaDB, Redis, workers, the scheduler, Socket.io and Nginx. Build or pull an image that contains your exact app versions, then load the restored files into the mounted volumes. The single-file demo setup is intended for short-lived evaluation only, so do not use it as the target for production data.
Import late changes with Data Import
Use this path only as a fix after the full restore, for example to bring in records created on Frappe Cloud after the backup was taken. The ERPNext Data Import tool loads CSV or Excel files using downloadable templates and supports child table rows. The documentation advises importing only a few thousand records at a time, so split large sets into batches and test one batch first.
Review Server Scripts, LDAP and social login
Use this path after restore, not as part of it. Server Scripts are disabled by default from version 15 and must be enabled with the server_script_enabled setting, and Frappe Cloud public shared benches do not allow them, so confirm which scripts your site depends on and enable them only where your policy allows. Then re-enter LDAP Settings or Social Login Key entries, which point at your own identity providers and callback addresses. Check each login path with a test user before DNS moves.
What drives the effort and cost of leaving Frappe Cloud
This table lists the factors that change how much work a move from Frappe Cloud to your own servers takes, and who pays for each one. Read each row against your own site: the drivers that are unknown today are usually the ones that extend the schedule. Most of the cost sits in one-time migration, testing and cutover work, while hosting, backups and upgrades recur after the move.
| Driver | Why it changes effort or cost | How to keep it down or what to ask for |
|---|---|---|
| Custom apps and version match | Each custom app must install on the same Frappe and ERPNext versions as the restored site, and apps not on Frappe Cloud need their source located and tested. | Ask for an inventory of every app, its source and its target version, and confirm each app has a release for your Frappe version. |
| Server Scripts to move or rewrite | Server Scripts run Python inside the site. From version 15 they are disabled by default and need the server_script_enabled setting, and self-hosting lets you choose whether to enable them. | Count scripts by document event and API endpoint. Ask whether each script moves as is, becomes a custom app, or is retired, and who tests it. |
| Payment, bank and ecommerce integrations | Connectors hold credentials and callback URLs tied to the old domain. Each one needs new endpoints, new secrets and a test transaction before cutover. | List every connector, its owner and its callback URL. Ask who issues new keys and who signs off test payments. |
| LDAP and Social Login Key reconfiguration | LDAP Settings and Social Login Keys store server addresses, TLS options and redirect URLs. Identity providers often need the new redirect URI registered before login works. | Ask for a settings export, a list of registered redirect URIs and a test login for each user group. |
| Data volume and file size | Database size, public files and private files all copy during backup download and restore. Larger sets lengthen transfer, restore and verification time. | Check the sizes of each backup part before quoting. Ask for a timed test restore on a copy of production. |
| Environments to stand up | A test restore, a parallel run and the production target each need a bench, database, Redis and TLS. Each extra environment adds build and configuration work. | Decide whether a test environment is required and how long parallel running lasts. Ask for each environment listed separately in the quote. |
| Acceptable write freeze | The final backup must reflect the last transaction, so users are locked out for the window between last backup and DNS switch. A shorter window requires a rehearsed sequence. | Agree the freeze length in writing, rehearse the sequence on a copy, and confirm who can approve an extension. |
| Internal Linux, database and DNS skills | Bench installation, database administration, TLS, DNS changes and scheduler setup need staff who can operate them. Gaps move work to a partner or extend testing. | Name the internal owners for each area. Ask the partner which tasks they would perform and which your team performs. |
| One-time costs | Scope analysis, environment build, app porting, test restores, integration retesting, DNS cutover and hypercare are paid once. Their size follows the rows above. | Ask for a fixed-scope quote with each one-time task, its deliverable and its acceptance test. |
| Recurring costs | Your own hosting, offsite backups, Frappe and ERPNext minor releases, security patches and support continue after cutover. Frappe Cloud plan prices are listed on the Frappe pricing page, and self-hosting software is free under the ERPNext license. | Ask who will take backups, test restores, apply upgrades and provide support, and what each recurring item costs in your environment. |
What usually goes wrong after the restore and how to prevent it
Most failed cutovers do not fail during the restore itself. They fail afterward, when versions drift, files go missing, jobs stop running, or traffic and writes still point at the old environment. Each card below names one risk, the step that prevents it, and the check that shows it is handled.
App version mismatch with the database
The restored database must run on the same ERPNext and Frappe versions it was created with, on a bench that has the same custom apps installed. Check the versions reported by the Frappe Cloud dashboard against your new bench before restoring, and confirm the supported upgrade path with Frappe's documentation for your release. After restore, run the migrate step and confirm the site loads without schema errors and that the version shown in the desk matches the source.
Missing private files and broken attachments
Public and private files are backed up separately, and a restore that brings in only the database leaves invoices, attachments and print files with dead links. Download the public and private files backups with the database and the site config backup, then place them in the site's files directories on the new bench. Verify the check by opening a sample of attached documents from several years back and by comparing file counts with the source backup.
Lost or mismatched encryption key
Site config holds the encryption key that Frappe uses to protect stored passwords and some sensitive fields, including integration credentials. If the key from the backup is not copied into the new site config, saved credentials cannot be decrypted and integrations fail silently. Copy the site config backup exactly, keep the original key in your secrets store, and confirm the setting with the Frappe documentation. The check is to open a stored integration credential or email account and confirm it authenticates.
Scheduler and background jobs not running
Recurring jobs such as email queues, reminders, and scheduled reports depend on the scheduler and background workers, which Frappe Cloud runs for you. On a self-hosted bench, these services must be enabled, supervised and restarted after a reboot, and the scheduler setting must match the site. Confirm the worker and scheduler processes are running after cutover and check the background jobs queue in the site for failed or stalled entries.
Email and integrations still pointing at Frappe Cloud
Outgoing email accounts, webhooks, OAuth redirect URLs, payment gateway callbacks and external systems that call the ERPNext API may still reference the old Frappe Cloud hostname or IP allowlist. Inventory every external endpoint before cutover, update each one to the new domain, and check whether any vendor requires a new callback registration. The check is a test transaction through each integration and a test email sent and received from the new site.
Incomplete final delta during cutover
If users keep posting invoices, stock entries or payments after the backup is taken, the restored site misses those writes. Plan a write freeze window, take the final offsite backup after users stop, and restore that backup rather than an earlier one. Compare document counts for the key transaction types between the source and the new site, and confirm the last posting timestamps match before DNS is switched.
How long and how much does it cost to move ERPNext from Frappe Cloud to self-hosted?
Does self-hosting ERPNext cost anything in software licensing?
No software license fee applies to self-hosting ERPNext, because ERPNext is free and open source under GPL-3.0 and the Frappe Framework is MIT licensed. The ERPNext pricing page states that self-hosting is free, so the money you move is hosting and labor. Frappe Cloud's current plan prices for comparison are published on the same pricing page: shared site hosting starts at 5 US dollars per month, shared servers start at 20 US dollars per month and dedicated servers start at 125 US dollars per month. Your recurring cost after the move is the infrastructure you choose, its backups, monitoring and the people who operate it. The one-time cost is the migration work itself, which is quoted from a written scope.
What drives the cost of moving ERPNext off Frappe Cloud?
The main drivers are the number of sites and apps to rebuild, the size of the database and file backups, and how many custom apps, scripts and integrations must be verified after restore. Cost also rises with the number of environments you want (staging, test restores, a parallel run) and with any change to the hosting design, such as TLS, reverse proxy, scheduler and background worker setup. Ask any provider, including DeployOpen, to quote these items separately: discovery and inventory, infrastructure build, restore and version matching, DNS cutover, post-cutover checks and handover. Ask which items recur, such as an ongoing support retainer, and which are one-time.
How long does it take to move ERPNext from Frappe Cloud to self-hosted?
Duration depends on the size and complexity of your site, the number of apps, the custom code that must be reviewed, and how quickly your team approves each step. Your team's readiness matters as much as the technical work: access to the Frappe Cloud dashboard, a backup marked offsite, a matching bench on the target servers and a agreed freeze window for the final backup all have to be in place. The offsite backup itself must be downloaded and restored successfully before any DNS change. Ask for a timeline in the written scope that lists each gate, who approves it and what evidence closes it.
What does our team need to provide during the move?
You need dashboard access to the Frappe Cloud site, permission to download offsite backups, and the target infrastructure with administrative access. You also need approvers who can sign off the version match, the restore test and the DNS cutover. A freeze window is required so no transactions are entered between the final backup and the switch. Name a finance owner who can confirm balances, open documents and reports after restore, because technical success does not prove the books are correct. Agree on who handles email, scheduled jobs and any third-party integration credentials during cutover.
Can our internal team move ERPNext alone, and what skills are required?
An internal team can do it if it has Linux administration, MariaDB and Redis experience, and working knowledge of the bench command line tool or the frappe_docker setup. Someone must also understand Frappe app versioning, site configuration, TLS, DNS and backup restore testing. Plan for the work to be tested on a non-production copy first. Server Scripts are disabled by default from version 15 and must be enabled with the server_script_enabled setting, so your team should check whether your site depends on them, since Frappe Cloud public shared benches do not allow them. Decide early whether you need external help for the parts your team has not run before.
Can I export backups from a lower Frappe Cloud plan?
Only backups marked offsite can be downloaded from the Frappe Cloud dashboard, and offsite backups are available on plans of USD 25 and above, according to the Frappe Cloud site backups documentation. If your current plan is below that level, confirm with Frappe whether an offsite backup can be obtained before you change plans, because the download path depends on the backup type. Each backup includes a database backup, public files backup, private files backup and site config backup, and all four are needed for a complete restore. Check the backup retention window before you downgrade or cancel, since an expired backup cannot be recovered.
What happens to Frappe warranty coverage when we leave Frappe Cloud?
Frappe's supported versions policy says warranty coverage requires a listed version and a matching Frappe Cloud support plan. If you leave Frappe Cloud and do not hold a matching support arrangement, you should expect that Frappe warranty coverage will not apply to your self-hosted site. Confirm the current terms directly with Frappe before you give notice, and ask whether any transition support is available. Independently, check that the version you deploy is still listed as supported on the supported versions page, because Frappe's published end-of-life dates affect which release line you can run.
How DeployOpen works on this
DeployOpen is a Chainscore Labs company that plans, implements, hardens, backs up, documents and supports self-hosted open-source platforms inside your own infrastructure. For a move off Frappe Cloud, we start from a written scope that names the offsite backup, the target bench, the app versions and the DNS cutover, then build and test the restore before any production switch.
How we scope
- Most engagements are fixed-scope, with scope, deliverables and timelines agreed in writing before work starts.
- The written scope lists the Frappe Cloud site, the ERPNext and companion app versions, and the offsite backup set to download.
- We confirm which Server Scripts, custom apps and integrations must be carried across and which are retired before cutover.
How we build
- We prepare a self-hosted bench on infrastructure you control, with Frappe and app versions matched to the Frappe Cloud site.
- We restore the database, public files, private files and site config into a staging site and check the restored data against the source.
- We test logins, scheduled jobs, email, print formats and integrations on staging, then document each gap found and its fix.
How we hand over
- You receive the restore runbook, the bench configuration, and the DNS cutover steps with rollback points.
- We record the version pinning, backup schedule and scheduler settings so your team can repeat the process and audit it later.
- We walk your administrators through the self-hosted site, including what Frappe Cloud previously managed for you and who now owns it.
How we support
- Ongoing support, upgrades and continuous testing are available as retainers after go-live.
- A retainer can cover patching to supported ERPNext minor releases and checks of the matching Frappe version on your bench.
- Support scope, response expectations and any SLA are set in the written agreement, so confirm them during scoping.

