Streamlining Frappe App Upgrades – Avoiding Data Loss and Friction

Title: Streamlining Frappe App Upgrades – Avoiding Data Loss and Friction

Category: Frappe Framework

Tags: upgrade migration data-loss suggestion


I’ve been self-hosting Frappe & Builder via the official easy-install Docker setup, and every time I pull a new “stable” image and run migrations, I’m terrified I’ll lose site data. Most recently I ran through the entire docker compose pull && bench --site all migrate && bench --site all build flow, and ended up with missing assets, 502s, and ultimately had to restore from backup because some critical doctypes and customizations disappeared.

I know part of it may be me—my workflow for zero-downtime doesn’t follow the “ideal” pattern—but it feels like upgrading any of the frappeverse apps (framework, erpnext, builder, etc.) should be a one-click, safe operation rather than a multi-step CLI dance that can silently drop data.

My environment & steps:

  1. Easy-install Python script → generates builder_prod_setup-compose.yml + .env
  2. docker compose pull && down && up -d --remove-orphans
  3. docker compose exec backend bench --site all migrate build clear-cache
  4. Hard-refresh browser → 404s, missing doctypes, broken hooks
  5. Restore from backup & repeat

Pain points:

  • No transactional “upgrade plan” – if one step fails, you’re left in a half-migrated state.
  • bench update inside a Docker image can’t detect branches, so I skip it and lose patch releases.
  • Assets (CSS/JS) often don’t copy correctly into sites/assets without manual bench build/assets.
  • No rollback mechanism beyond full database restore.

Questions & suggestions:

  1. Is there a recommended Docker-native upgrade workflow that ensures migrations run safely and atomically?
  2. Could Frappe provide a bench upgrade GUI (or API endpoint) inside Desk to automate pulls, migrations, build, and cache-clear?
  3. Are there plans to support an officially idempotent upgrade process (like Kubernetes operators or a Helm chart) that guards against partial failures?

I’d love to hear how others are handling seamless upgrades in production, and of course, if the core team is open to improving the user experience here, I’m happy to help test or contribute. Thanks!

1 Like

As a system admin, I cringe when apps only distribute via Docker images. I’m thankful Frappe allows installation directly on my Linux host.

In my opinion, Docker is a great tool for developing but not deploying in a production environment (from a sysadmin perspective). I much prefer system access. I’m sure my inexperience with Containers and my age have made me biased :wink:

I typically have at least three servers (dev, test, prod). I can test upgrades on the test system before running them on the production server. I can run development branches on my dev server, for things like pull requests.

I also have the same scenario for each version (three servers for v14 & three for v15). I don’t do any dev work on v14, so now it’s just test & prod for v14.

2 Likes

I’ll echo @volkswagner: the issues you’re describing here sound like docker problems. I know some people love docker, but I’ve just never been able to get it to work quite right for a complex application stack with many moving parts like Frappe.

There used to be a bench GUI developed by the community, but I don’t think it got much traction. I think most people saw it as just another abstraction layer without much benefit. Press offers a gui interface for upgrades, but it’s a very different use case.

As far as the upgrade process goes, what are you currently encountering that’s not idempotent? I do wish bench would be a bit more explicit about its behaviors, but I think a simple bench update call is already idempotent or at least very close to it.

2 Likes

I build the docker image myself thus never faced this issue. Probably the issue is with how the image was built.