Most guides get you to a login page and stop, which is the point at which ERPNext deployments start going wrong. Queued jobs, scheduled emails and reports live outside the web tier, and when they stop the interface looks perfectly healthy. This walks the install and then the operational facts that keep it working after the first month.

ERPNext is the largest thing most teams ever self-host. It is not a web app with a database; it is the Frappe framework, a job queue, a scheduler, a websocket server and a set of site directories, all managed by a tool that expects to own the machine. Install it accordingly and it is stable for years.

What You Are Actually Installing

Five processes have to be running for a working system, and knowing them makes every later problem diagnosable.

The web workers serve requests. The background workers run queued jobs in short, default and long queues, which is where reports, emails and imports happen. The scheduler enqueues recurring work. A socketio process pushes real-time updates to the browser. Redis backs the queue and the cache. Behind them sit MariaDB and a directory tree per site.

If reports never finish or scheduled emails never arrive while the interface works perfectly, a background worker or the scheduler has stopped. That is the single most common ERPNext support question and it has nothing to do with the web tier.

Sizing It Honestly

ERPNext is memory-hungry because each worker is a Python process holding the framework in memory, and there are several of them.

ScalevCPU / RAM / SSDMonthly on per-resource pricing
Evaluation, 1-3 users2 / 4 GB / 40 GB$9.34
Small business, 5-15 users4 / 8 GB / 80 GB$18.68
Growing, 20-50 users8 / 16 GB / 160 GB$37.36
Multi-site or heavy reporting16 / 32 GB / 320 GB$74.72

Those figures use MassiveGRID's per-resource rates of $2.87 per CPU core, $0.80 per GB of RAM and $0.01 per GB of SSD per month, so the 4/8/80 row is $11.48 plus $6.40 plus $0.80. Annual billing takes 20% off.

Do not try to run production on 2 GB. It installs, it starts, and the first bulk import or report kills a worker with an out-of-memory error. Our guide to sizing self-hosted applications covers the reasoning behind these shapes.

Install With the Easy Install Script

There are three installation routes and only one of them is a good idea for a first deployment. Manual bench installation gives you the most control and the most opportunities to get a dependency version wrong. The Docker route is excellent and is a different operational model. The easy install script sits between them and is what to use.

sudo apt update && sudo apt install -y python3-dev python3-pip git curl
curl -fsSL https://raw.githubusercontent.com/frappe/bench/develop/easy-install.py -o easy-install.py
python3 easy-install.py deploy \
  --project erpnext \
  --email you@example.com \
  --sitename erp.example.com \
  --app erpnext

Read the script before running it, as you would with anything piped from the internet. It provisions Docker, MariaDB, Redis and the Frappe stack, and it will happily reconfigure things on a host that is already doing something else, so give ERPNext its own server.

The --sitename must be the hostname users will actually type. Frappe resolves sites by the Host header, so a site created as localhost and later accessed by domain returns a "site does not exist" error that looks like a broken install.

The bench Commands Worth Knowing

bench --site erp.example.com backup --with-files
bench --site erp.example.com set-config maintenance_mode 1
bench --site erp.example.com migrate
bench --site erp.example.com clear-cache
bench restart
bench doctor                     # queue and scheduler health

bench doctor is the first thing to run when something asynchronous has stopped. bench migrate applies schema changes and must run after any app update, and skipping it leaves an interface that half works.

Note that --with-files is not the default. A backup without it contains the database and none of the attachments, which is not a backup of an ERP system where every invoice has a PDF attached to it.

The Two Directories That Are Your Data

ERPNext keeps uploaded files outside the database, in public/files for anything shareable and private/files for attachments that respect permissions. A database dump alone restores an ERP whose every document link is broken.

Back up the database and both file directories together, as one consistent set, and restore both in a rehearsal before you rely on it. Then take the backup somewhere else: backup services use block-level incremental backups with AES-256 encryption at $0.01 per GB, which for an ERPNext site is a rounding error against the cost of reconstructing it.

Put the site in maintenance mode before a backup you intend to restore from. A dump taken while invoices are being posted is consistent as a database and may not be consistent as a business record.

Upgrades Are the Commitment

Frappe and ERPNext move quickly, and custom fields, custom scripts and third-party apps are what make an upgrade interesting rather than routine. Version jumps can change API behaviour that customisations depend on.

Never upgrade production first. Restore a backup onto a second server, upgrade that, and have someone who uses the system daily click through their real workflows. Keep a list of every customisation and every installed app, because the upgrade will test each one and you want to know what to check rather than discovering it from a user. Our guide to upgrading self-hosted applications covers the general pattern, including why a schema migration makes rollback harder than it looks.

The Things That Break First

Scheduler disabled. After a restore, the scheduler is often left off. Nothing recurring runs and nothing complains. bench doctor reports it.

Queue backed up. A long job blocking the long queue delays everything behind it. Watch queue depth, not just CPU.

Email not configured. ERPNext sends a lot of mail, and a default configuration means invoices silently do not reach customers. Use an authenticated relay with SPF, DKIM and DMARC on the sending domain.

Disk full from backups. The default backup location is on the same disk as the site, and old backups are not pruned aggressively. This fills the disk and takes the site down.

Infrastructure for a System the Business Runs On

An ERP outage stops invoicing, stock movements and payroll, which puts it in a different availability class from an internal wiki.

MassiveGRID's platform runs Proxmox high-availability clustering with automatic failover over Ceph storage replicating every block three times across independent NVMe drives, behind a 100% uptime SLA, so a host failure restarts the guest rather than ending the day. A Linux VPS at the per-resource rates above suits most deployments; where the ERP is genuinely business-critical, high-availability cloud servers add managed operations from $9.99 plus $5 management, and DevOps support covers the upgrade rehearsals if nobody internally owns them.

Servers can be ordered across a partner footprint of more than 700 datacenters in 85 metros, 30 countries and six continents, with auto-provisioning in New York, London, Frankfurt and Singapore.

Further Reading