How to Install ERPNext on Ubuntu 24.04 VPS: Self-Hosted Open-Source ERP via Frappe
Running a full ERP system on infrastructure you control means your general ledger, customer records, inventory data, and payroll never leave your server. ERPNext is the most complete open-source ERP available today, and this guide walks you through installing ERPNext v15 on an Ubuntu 24.04 VPS using the official Frappe Bench tooling -- from the first apt update to a production-hardened deployment serving your browser over HTTPS.
Skip the manual install? Our CloudCore Business VPS is sized specifically for ERPNext workloads -- 8 GB RAM, 4 vCPU, NVMe SSD -- and can be provisioned in under 60 seconds. Follow the steps below on your fresh server and you will have a working ERP in under an hour.
Table of Contents
What is ERPNext?
ERPNext is a full-featured, open-source enterprise resource planning (ERP) system built on top of the Frappe Framework, a Python + JavaScript low-code platform maintained by Frappe Technologies. It is licensed under the GNU GPL v3, which means you can install, modify, and run it on any number of servers with no per-user fees, no feature gating, and no vendor lock-in.
ERPNext is not a minimal ERP -- it is a complete business operating system. Out of the box you get double-entry Accounting with multi-currency GL, AP/AR, bank reconciliation, and 100+ built-in reports; Inventory and Warehouse Management with serial/batch tracking, stock ledgers, and barcode support; Manufacturing with bill of materials, work orders, production planning, and subcontracting; Human Resources and Payroll covering employees, leave, attendance, salary slips, and tax computation; CRM with leads, opportunities, quotations, and a full sales pipeline; Projects with tasks, timesheets, and billing; Retail and POS with offline-capable point of sale; Asset Management with depreciation schedules; Quality Management; Website and Portal; and a native REST API that exposes every single document type for integration.
The Frappe Framework underneath ERPNext is what makes it genuinely extensible. Everything in the system -- fields, forms, reports, permissions, workflows, print formats -- is metadata-driven. You can add a custom field to the Sales Invoice, create a new "Service Contract" DocType, or script server-side business logic without touching core code. That metadata survives upgrades, which is why large organizations choose ERPNext over locked-down SaaS ERP.
The ERPNext community is active. The upstream repository receives hundreds of commits per month, a major release lands annually (v14, v15, v16), and a vibrant ecosystem of paid and free apps exists at frappe.io/apps -- including HR, CRM, LMS, Helpdesk, Insights (BI), Drive (file storage), and Builder (no-code site builder).
Common deployment patterns for self-hosted ERPNext include:
- Small businesses replacing QuickBooks + separate inventory + separate CRM with a single integrated stack.
- Manufacturers running shop-floor BOM, work orders, and material requirements planning (MRP).
- Distributors and retailers unifying multi-warehouse inventory with POS and e-commerce.
- Services companies managing projects, timesheets, recurring invoicing, and subscriptions.
- Nonprofits and schools using Frappe's free Education and Nonprofit modules on top of ERPNext.
Why Self-Host ERPNext on Your VPS?
Running ERPNext on your own VPS instead of paying for the hosted Frappe Cloud or moving to a closed-source ERP (NetSuite, SAP Business One, Dynamics 365 Business Central) has concrete advantages:
- No per-user fees -- Closed-source ERPs charge USD 100-250 per user per month. Frappe Cloud charges per site and per user above a threshold. Self-hosted ERPNext is unlimited: 5 users or 500 users, same server cost.
- Full data ownership -- The entire database, file storage, and backups live on a disk you control. No third party can lock you out, suspend your account, or mine your data.
- Complete customization -- Add custom fields, DocTypes, reports, and server scripts. Install any of the 100+ Frappe apps. Fork the source if you need to.
- Regulatory compliance -- For GDPR, HIPAA, or jurisdiction-specific data residency rules, running on a VPS in a known region (EU, US, Canada) simplifies your compliance story.
- Predictable flat-rate cost -- A VPS is a fixed monthly bill regardless of transaction volume. No surprise SaaS price hikes at renewal.
- Offline capability -- Run on a LAN-connected box in a factory or remote site with intermittent internet. Sync back to a central instance when connectivity returns.
- Air-gapped deployments -- Install in isolated networks for government, defense, or high-security environments where SaaS is not an option.
Cost Comparison: Self-Hosted vs. Hosted SaaS ERP
| Scenario | NetSuite | Frappe Cloud (managed) | Self-Hosted ERPNext (VPS) |
|---|---|---|---|
| Base monthly cost | USD 999+ /mo | USD 25-100+ /mo | EUR 24.99 /mo |
| Cost per additional user | USD 100-250 /user/mo | USD 10+ /user/mo | Included (unlimited) |
| Typical all-in for 10 users | USD 2,000-3,500 /mo | USD 125-200 /mo | EUR 24.99 /mo |
| Data location | SaaS (shared) | Managed (Frappe) | Your VPS |
| Custom apps / server scripts | Paid SuiteCloud add-on | Supported | Full access |
| Source code access | No | No | Yes (GPL) |
| Admin shell access | No | Limited | Full root |
Prerequisites
Before starting, make sure you have:
- A VPS running Ubuntu 24.04 LTS with root or sudo access.
- SSH access to your server (PuTTY on Windows, built-in terminal on macOS/Linux).
- At least 4 GB of RAM (8 GB+ strongly recommended for production with 5+ concurrent users).
- At least 40 GB of free disk space for the OS, MariaDB data, Frappe apps, Node modules, backups, and file attachments.
- A domain name pointing to your server's IP via an A record (required for HTTPS). You can skip this and use
site1.localfor local testing. - Ports 80 and 443 open in your firewall / provider security group if you plan to expose the site publicly.
Recommended Plan: CloudCore Business>
ERPNext runs MariaDB, Redis (three instances), Python workers, a Node socketio server, and Nginx -- it is a real stack. For production deployments we recommend the CloudCore Business plan:>
- 4 vCPU cores
- 8 GB RAM
- 100 GB NVMe SSD
- Unmetered bandwidth
- EUR 24.99 / month>
That is enough headroom for 20-30 concurrent users, a database in the low tens of GB, and full backups on-disk. Smaller teams can run on 4 GB RAM but should expect occasional worker restarts under load.
Connect to your server via SSH to begin:
ssh root@your-server-ipStep 1: Update System Packages
Start by updating the package index and upgrading installed packages so dependency resolution works cleanly and security patches are applied.
sudo apt update && sudo apt upgrade -yExpected output (abbreviated):
Hit:1 http://archive.ubuntu.com/ubuntu noble InRelease
Hit:2 http://archive.ubuntu.com/ubuntu noble-updates InRelease
Reading package lists... Done
Building dependency tree... Done
Calculating upgrade... Done
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.Set your hostname (optional but recommended) so logs and MariaDB are easier to identify:
sudo hostnamectl set-hostname erpnextSet the timezone to match your business (ERPNext uses the system timezone for scheduled jobs):
sudo timedatectl set-timezone Europe/BerlinIf the kernel was updated, reboot before continuing:
sudo rebootStep 2: Install System Dependencies
ERPNext / Frappe requires Python 3.10+, a C toolchain for building Python and Node native modules, Git, and a handful of system libraries. Ubuntu 24.04 ships with Python 3.12 by default, which is supported by Frappe v15.
Install the base dependencies:
sudo apt install -y git curl wget build-essential \
python3-dev python3-pip python3-venv python3-setuptools \
software-properties-common \
libffi-dev libssl-dev \
libjpeg-dev zlib1g-dev \
libxml2-dev libxslt1-dev libtiff5-dev libpng-dev \
libwebp-dev libharfbuzz-dev libfribidi-dev libxcb1-dev \
xvfb libfontconfig \
cron supervisorVerify Python and pip:
python3 --version
pip3 --versionExpected output:
Python 3.12.3
pip 24.0 from /usr/lib/python3/dist-packages/pip (python 3.12)Ubuntu 24.04's pip is PEP 668 "externally-managed" -- you cannot pip install globally. This is fine: Frappe Bench installs into a virtualenv per bench, and we will install frappe-bench itself with --break-system-packages in Step 7, which is the upstream-documented approach.
Step 3: Install and Configure MariaDB 10.6
Frappe v15 officially supports MariaDB 10.6+. Ubuntu 24.04's default MariaDB is 10.11, which works. If you want to pin to 10.6 exactly, use the MariaDB apt repository; for most users the default is fine.
Install MariaDB server and client:
sudo apt install -y mariadb-server mariadb-clientStart and enable the service:
sudo systemctl enable --now mariadb
sudo systemctl status mariadbExpected output:
mariadb.service - MariaDB 10.11.x database server
Loaded: loaded (/lib/systemd/system/mariadb.service; enabled; preset: enabled)
Active: active (running) since Wed 2026-04-16 10:05:12 UTC; 10s agoRun the secure installation to set a root password and remove test defaults:
sudo mariadb-secure-installationAnswer the prompts:
- Enter current password for root: press Enter (blank)
- Switch to unix_socket authentication?:
n - Change the root password?:
Y-- set a strong password and save it - Remove anonymous users?:
Y - Disallow root login remotely?:
Y - Remove test database?:
Y - Reload privilege tables now?:
Y
Create a Frappe-specific config file:
sudo tee /etc/mysql/mariadb.conf.d/99-frappe.cnf > /dev/null <<'EOF' [mysqld] character-set-client-handshake = FALSE character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ciinnodb-file-format = Barracuda innodb-file-per-table = 1 innodb-large-prefix = 1 innodb-default-row-format = dynamic
Performance
innodb-buffer-pool-size = 2G max_allowed_packet = 512M
[mysql] default-character-set = utf8mb4 EOF
Adjust innodb-buffer-pool-size to roughly 25-50% of your total RAM (2G for an 8 GB server, 4G for 16 GB).
Restart MariaDB to apply:
sudo systemctl restart mariadbVerify the server is using utf8mb4:
sudo mariadb -e "SHOW VARIABLES LIKE 'character_set_server'; SHOW VARIABLES LIKE 'collation_server';"Expected output:
+----------------------+---------+
| Variable_name | Value |
+----------------------+---------+
| character_set_server | utf8mb4 |
+----------------------+---------+
+-------------------+--------------------+
| Variable_name | Value |
+-------------------+--------------------+
| collation_server | utf8mb4_unicode_ci |
+-------------------+--------------------+For a deeper dive on MariaDB tuning see our MariaDB on Ubuntu 24.04 guide.
Step 4: Install Redis, Node.js, and Yarn
Frappe uses Redis for caching, the task queue, and the real-time socketio backend. Node.js is required to build the JavaScript assets (client-side desk, reports, and print formats), and Yarn is the package manager Frappe bench uses.
Install Redis:
sudo apt install -y redis-server
sudo systemctl enable --now redis-serverVerify:
redis-cli pingExpected output:
PONGFor more on Redis tuning, see our Redis installation guide.
Install Node.js 18 LTS via NodeSource (Ubuntu 24.04's default is Node 18, but installing the NodeSource repository ensures you can pin and upgrade cleanly):
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install -y nodejsVerify:
node --version
npm --versionExpected output:
v18.20.4
10.7.0Install Yarn globally:
sudo npm install -g yarn
yarn --versionExpected output:
1.22.22Step 5: Install wkhtmltopdf 0.12.6 with Patched Qt
ERPNext uses wkhtmltopdf to render PDF print formats (invoices, quotations, reports). You must install version 0.12.6 with patched Qt -- the version in Ubuntu's repositories (0.12.6 unpatched) produces broken PDFs with missing fonts and incorrect table layouts. This is the single most common ERPNext install mistake.
Download and install the upstream patched build:
cd /tmp
wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox_0.12.6.1-3.jammy_amd64.deb
sudo apt install -y ./wkhtmltox_0.12.6.1-3.jammy_amd64.debThe Jammy (Ubuntu 22.04) package works on Noble (24.04) because its Qt dependencies are statically linked. As of 2026 there is no Noble-specific release yet, and the Jammy build is the supported path.
Verify the installation explicitly reports "patched qt":
wkhtmltopdf --versionExpected output:
wkhtmltopdf 0.12.6.1 (with patched qt)If the output says "without patched qt" or shows a lower version, remove it and reinstall:
sudo apt remove -y wkhtmltopdf wkhtmltoxThen re-run the download and install from above.
Step 6: Create the Frappe User
Running Frappe as root is not supported. Create a dedicated non-root user (we use frappe) with passwordless sudo only during the install -- you can remove that privilege later.
Create the user:
sudo adduser --disabled-password --gecos "" frappe
sudo usermod -aG sudo frappeGrant temporary passwordless sudo so bench's production setup step can run supervisor / nginx commands:
echo "frappe ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/frappe
sudo chmod 0440 /etc/sudoers.d/frappeSwitch to the frappe user and change into their home directory:
sudo su - frappe
cd ~All remaining steps in Step 7 through Step 10 run as the frappe user unless explicitly stated.
Step 7: Install Frappe Bench
Frappe Bench is the CLI tool that orchestrates Frappe / ERPNext installations. It creates the directory layout, manages Python virtualenvs, runs migrations, configures supervisor/nginx, and handles updates.
Install it via pip (still as the frappe user):
pip3 install --user --break-system-packages frappe-benchAdd the user's local bin directory to your PATH:
echo 'export PATH=$HOME/.local/bin:$PATH' >> ~/.bashrc
source ~/.bashrcVerify:
bench --versionExpected output:
5.22.6Step 8: Initialize the Bench and Create a Site
A "bench" is a directory containing one or more Frappe apps and one or more sites (databases). You typically have a single bench per server.
Initialize a new bench on the v15 branch:
cd ~
bench init --frappe-branch version-15 frappe-benchThis command:
~/frappe-bench/ with the standard layout (apps/, sites/, config/, env/).~/frappe-bench/env/.version-15 branch into ~/frappe-bench/apps/frappe/.yarn install and builds the initial JavaScript bundles.Expected output (abbreviated):
Setting up directories
Setting up env
Setting up redis as cache backend...
Installing frappe
...
Done in 120.45s.
SUCCESS: Bench frappe-bench initializedThis step takes 3-8 minutes depending on CPU and bandwidth. If it fails mid-way, delete ~/frappe-bench/ and re-run -- partial state is not recoverable.
Change into the bench directory:
cd ~/frappe-benchCreate your first site. Replace site1.local with your real domain (e.g. erp.yourcompany.com) if you have one pointed at this server -- it makes the Nginx setup in Step 10 seamless.
bench new-site site1.local \
--db-root-password YourMariaDBRootPassword \
--admin-password YourAdminPasswordExpected output:
Creating new site site1.local
Scheduler is disabled
Installing frappe...
Updating DocTypes for frappe : [========================================] 100%
Updating Dashboard for frappe
Scheduler is disabled
Current Site set to site1.localWhat just happened:
- Bench created a MariaDB database named
_<hash>and a dedicated DB user with the same name. - Bench wrote
~/frappe-bench/sites/site1.local/site_config.jsonwith DB credentials. - Bench ran Frappe's migrations on the new database.
- The Administrator password you passed is the login for the
Administratoruser.
Step 9: Install ERPNext and Additional Apps
At this point you have a working Frappe installation, but no ERP functionality yet. Install ERPNext itself:
bench get-app erpnext --branch version-15This clones the ERPNext repository into ~/frappe-bench/apps/erpnext/ and installs its Python dependencies. It takes 2-5 minutes.
Expected output (abbreviated):
Getting erpnext
$ git clone https://github.com/frappe/erpnext --branch version-15 --depth 1
...
Installing erpnext
Resolving dependencies...
Installed erpnextNow install ERPNext onto your site:
bench --site site1.local install-app erpnextExpected output:
Installing erpnext...
Updating DocTypes for erpnext : [========================================] 100%
Updating customizations for Address
Updating customizations for Contact
Scheduler is disabled This step typically takes 3-6 minutes on an 8 GB VPS -- ERPNext has 700+ DocTypes to install and migrate.
Install Additional Apps (Optional)
ERPNext v15 extracted several modules into separate apps. If you need HR, Payroll, CRM, or Payments, install them now:
# HR + Payroll
bench get-app hrms --branch version-15
bench --site site1.local install-app hrmsCRM (standalone v2 CRM, separate from ERPNext Leads/Opportunities)
bench get-app crm --branch main
bench --site site1.local install-app crmPayments (Stripe, PayPal, Razorpay, etc.)
bench get-app payments --branch version-15
bench --site site1.local install-app paymentsYou can install these later at any time with the same two-command pattern (bench get-app then bench --site ... install-app).
Verify in Development Mode
Before switching to production, do a quick smoke test. Start the built-in dev server:
bench startThis runs Frappe's Python web server on port 8000, the socketio server on 9000, the Redis instances, and the background workers -- all in one terminal via Honcho.
Open a second SSH session and curl:
curl -H "Host: site1.local" http://localhost:8000Expected: HTML output containing <title>Login</title>.
Stop the dev server with Ctrl+C. We will switch to production-grade Nginx + supervisor next.
Step 10: Switch to Production Mode
Production mode replaces bench start with:
- Supervisor managing the Python web workers (Gunicorn), background workers (RQ), scheduler, and socketio server.
- Nginx serving static assets directly and reverse-proxying dynamic requests.
- fail2ban filters for brute-force protection on the login endpoint.
frappe user, run:sudo bench setup production frappeThe frappe argument is the Linux user that supervisor will run processes as -- it should match your bench owner.
Expected output (abbreviated):
$ sudo supervisorctl reread $ sudo supervisorctl update $ sudo systemctl reload nginx Port configuration list:
Site site1.local assigned port: 80
What just happened:
/etc/supervisor/conf.d/frappe-bench.conf with process definitions for frappe-bench-frappe-web (Gunicorn), frappe-bench-frappe-schedule, frappe-bench-frappe-short-worker, frappe-bench-frappe-default-worker, frappe-bench-frappe-long-worker, and frappe-bench-node-socketio./etc/nginx/conf.d/frappe-bench.conf with a virtual host listening on port 80, serving static assets from ~/frappe-bench/sites/assets/, and proxying /api/method/ and /app to the Gunicorn socket.Verify supervisor is running the bench processes:
sudo supervisorctl statusExpected output:
frappe-bench-redis:frappe-bench-redis-cache RUNNING
frappe-bench-redis:frappe-bench-redis-queue RUNNING
frappe-bench-redis:frappe-bench-redis-socketio RUNNING
frappe-bench-web:frappe-bench-frappe-web RUNNING
frappe-bench-web:frappe-bench-node-socketio RUNNING
frappe-bench-workers:frappe-bench-frappe-schedule RUNNING
frappe-bench-workers:frappe-bench-frappe-short-worker RUNNING
frappe-bench-workers:frappe-bench-frappe-default-worker RUNNING
frappe-bench-workers:frappe-bench-frappe-long-worker RUNNINGVisit http://your-server-ip/ (or http://site1.local/ if you have DNS configured). You should see the ERPNext login page.
For more on Nginx configuration patterns, see our Nginx on Ubuntu 24.04 guide.
Step 11: Enable HTTPS with Let's Encrypt
Bench ships with a wrapper around Certbot that handles issuance, Nginx reconfiguration, and renewal in one step. This is the recommended path for ERPNext HTTPS.
Before running this, make sure:
- Your domain's A record points to this server's public IP.
- Ports 80 and 443 are open.
- The site name you used in
bench new-sitematches the domain (e.g.erp.yourcompany.com). If you usedsite1.local, see the "Rename a site" note below.
sudo -H bench setup lets-encrypt site1.localExpected prompts and output:
Running Pre Setup...
Enabling HTTPS only on Nginx...
Do you want to continue? [y/N]: yBench invokes Certbot in Nginx plugin mode, provisions a certificate at /etc/letsencrypt/live/site1.local/, rewrites the Nginx config to listen on 443 with the cert, and adds an HTTP-to-HTTPS redirect. A cron job for renewal is installed automatically at /etc/cron.d/certbot.
Verify HTTPS:
curl -I https://site1.localExpected output:
HTTP/2 200
server: nginx
content-type: text/html; charset=utf-8Rename a Site to Match Your Domain
If you created the site as site1.local but want it on erp.yourcompany.com, rename it before enabling HTTPS:
bench --site site1.local set-config host_name https://erp.yourcompany.com
bench use erp.yourcompany.com
Or, to actually rename the database-side name:
bench rename-site --new-name erp.yourcompany.com site1.local
bench setup nginx --yes
sudo systemctl reload nginxFor more on TLS, see our Let's Encrypt + Certbot guide.
Post-Install: First Login and Company Setup
Open https://erp.yourcompany.com/ (or whatever domain you used) in a browser. You will land on the login page.
Log in as:
- Email / Username:
Administrator - Password: the admin password you set in Step 8
AC for "Acme Corp") appears in account codes.The wizard takes 2-3 minutes. Behind the scenes it creates the Company record, default Chart of Accounts, default warehouses, default Tax Templates, and grants the System Manager role.
Once complete, you land on the ERPNext desk. Key first steps:
- Create your first Customer (from the Selling module).
- Create your first Item (from the Stock module) with a valuation rate.
- Create a Sales Invoice to confirm accounting postings work.
- Check the General Ledger report to see the accounting entries.
Backups and Updates
Taking Backups
Frappe has a built-in backup command that exports the site database plus file attachments:
cd ~/frappe-bench
bench --site erp.yourcompany.com backup --with-filesExpected output:
Backup Summary for erp.yourcompany.com as of ...
Config : ./sites/erp.yourcompany.com/private/backups/..._site_config_backup.json
Database: ./sites/erp.yourcompany.com/private/backups/..._database.sql.gz
Public : ./sites/erp.yourcompany.com/private/backups/..._files.tar
Private : ./sites/erp.yourcompany.com/private/backups/..._private_files.tarThe --with-files flag is essential for disaster recovery -- without it, uploaded attachments are lost.
Scheduled Backups
Frappe writes scheduled backups on a rotation automatically (configured in Common Site Config). Verify the cron is active:
crontab -lYou should see a line invoking bench backup-all-sites. To increase retention or offsite-copy backups to S3/Backblaze/rsync, edit the cron and add an aws s3 cp or rclone copy step on the backup directory.
Updating ERPNext
To upgrade to a newer patch version within v15:
cd ~/frappe-bench
bench updateThis pulls the latest code from each app, runs yarn and bench build, runs database migrations, and restarts supervisor workers.
To upgrade to a new major version (e.g. v15 -> v16), pin each app to the new branch first:
bench switch-to-branch version-16 frappe erpnext hrms --upgrade
bench updateAlways back up before a major version upgrade. Review the v15 -> v16 migration notes before running.
Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
| PDF print formats blank or garbled | wkhtmltopdf without patched Qt | Run wkhtmltopdf --version -- must say "with patched qt". Remove the Ubuntu-repo package and install the 0.12.6.1-3 deb from Step 5. |
socketio.connect() failed in browser console, real-time updates dead | Node socketio worker not running or Nginx not proxying /socket.io/ | Check sudo supervisorctl status</td><td>grep socketio<code>. Verify </code>/etc/nginx/conf.d/frappe-bench.conf<code> contains </code>location /socket.io/ { proxy_pass http://frappe-bench-socketio-server; }<code>. Run </code>bench setup socketio && bench setup nginx --yes && sudo systemctl reload nginx. |
| Nginx fails to start: "bind() to 0.0.0.0:80 failed" | Apache or another service already owns port 80 | sudo ss -tlnp</td><td>grep :80<code> to identify. Stop/uninstall Apache: </code>sudo systemctl disable --now apache2. |
pymysql.err.OperationalError: (1071, 'Specified key was too long') during site create | MariaDB not configured for utf8mb4 / Barracuda | Confirm /etc/mysql/mariadb.conf.d/99-frappe.cnf is present and sudo systemctl restart mariadb. Recreate the site. |
ModuleNotFoundError: No module named 'frappe' | Running bench commands outside the virtualenv | Always run bench from inside ~/frappe-bench/. Don't sudo bench except during the setup production step. |
Site shows "Internal Server Error" after bench update | Stale assets or failed migration | Run bench migrate && bench build && bench restart. Check ~/frappe-bench/logs/web.error.log for the Python traceback. |
| Login slow or timing out under load | Too few Gunicorn workers for your RAM | Edit ~/frappe-bench/config/gunicorn.conf.py and raise workers to (2 * vcpu) + 1. Then bench setup supervisor --yes && sudo supervisorctl reload. |
bench setup lets-encrypt fails with "DNS problem" | A record not propagated or wrong IP | dig +short erp.yourcompany.com must return your server's IP. Wait for DNS propagation (up to 30 min) and re-run. |
| Redis connection refused on port 11000/12000/13000 | Frappe's internal Redis instances not started | bench setup redis && bench restart. These ports are bench-managed Redis instances separate from the system's redis-server. |
| High memory use, OOM killer hitting workers | MariaDB buffer pool + Gunicorn workers exceeds RAM | Lower innodb-buffer-pool-size in 99-frappe.cnf, reduce Gunicorn workers, or upgrade to 16 GB RAM. |
Viewing Logs
The most useful logs during debugging:
tail -f ~/frappe-bench/logs/web.error.log # Python tracebacks from Gunicorn
tail -f ~/frappe-bench/logs/worker.error.log # Background job failures
tail -f ~/frappe-bench/logs/bench.log # bench CLI operations
sudo tail -f /var/log/nginx/error.log # Nginx-level errors
sudo journalctl -u supervisor -f # Supervisor control messagesFAQ
What is the difference between Frappe and ERPNext?
Frappe is the underlying full-stack low-code framework -- a Python web framework with a JavaScript client, a metadata-driven ORM (DocTypes), a REST API, permissions, workflows, and a desktop-like UI called "the desk." It is the platform. ERPNext is a collection of Frappe apps that implement ERP features on top of that platform -- accounting, inventory, manufacturing, and so on. You can run Frappe without ERPNext (for example to build a custom internal tool), but ERPNext always requires Frappe. Installing "ERPNext" via bench installs both, which is why the directory layout includes apps/frappe/ and apps/erpnext/ side by side.
Can I run ERPNext on 4 GB RAM?
Yes, for small-scale or single-user setups. The stack (MariaDB + 3 Redis + Gunicorn + 3 workers + Node socketio + Nginx) will fit in 4 GB RAM for light use (1-3 users, small database). For anything production-shaped -- 5+ concurrent users, reasonable database size, PDF generation load -- plan for 8 GB minimum. If you try 2 GB you will see OOM kills during report generation and bench update will fail.
Do I need Docker to install ERPNext?
No. The bench / supervisor / Nginx install documented here is the upstream-recommended path for production and is what Frappe Technologies runs for Frappe Cloud. Docker (via the frappe_docker repository) is an alternative deployment model that some teams prefer for Kubernetes or multi-tenant scenarios. For a single-company ERP on a single VPS, bench + supervisor is simpler, better documented, and easier to debug.
How do I host multiple sites on one server?
A bench supports many sites sharing the same apps and the same supervisor/nginx stack -- each site is a separate MariaDB database. Create additional sites with bench new-site site2.yourcompany.com --db-root-password X --admin-password Y and then bench setup nginx --yes && sudo systemctl reload nginx. Nginx routes by the Host header, so each site needs its own DNS A record pointed at the server. You can install a different combination of apps on each site -- for example, site1 runs ERPNext + HRMS, site2 runs only Frappe + a custom app.
Is ERPNext v15 production-ready for a real business?
Yes. ERPNext v15 is the current stable major version as of 2026, used by tens of thousands of businesses worldwide including publicly listed companies. The version-15 branch receives only bug fixes and minor features; new feature development targets develop (which becomes v16). Self-hosting gives you full control over when you upgrade to v16 -- you are not forced to move until you choose to. Pair your install with disciplined backups (Step 12), a staging clone for testing updates, and log monitoring, and it is as production-ready as any SaaS ERP.
How do I integrate ERPNext with my existing tools?
ERPNext exposes every DocType via a REST API at /api/resource/<DocType> and method endpoints at /api/method/<module.method>. Authenticate via an API key + secret generated per user in the desk UI (User -> API Access). From there, typical integrations include Stripe/PayPal via the Payments app, e-commerce storefronts pushing orders via the REST API, BI tools (Metabase, Superset, Grafana) reading directly from MariaDB, Zapier / n8n / Make webhooks via the built-in Webhook DocType, and LDAP/SSO via built-in support for LDAP, OAuth 2, and SAML. The REST API schema is stable across patch releases.
Next Steps
Now that ERPNext is running on your VPS, here are recommended next steps:
- Set up automated offsite backups -- Frappe's on-disk backup is a starting point; replicate it nightly to S3, Backblaze B2, or rsync.net with
rcloneoraws s3 syncso a disk failure does not lose your ledger. - Install Insights for BI dashboards -- Frappe Insights is a free, open-source BI app that queries your ERPNext database directly. Install with
bench get-app insights && bench --site ... install-app insights. - Add email sending via SMTP -- Configure outgoing mail in Email Domain + Email Account so ERPNext can send invoices, password resets, and notifications. Use a transactional provider (Postmark, Amazon SES, Brevo) or your own Mailcow instance.
- Harden the server -- Install UFW, disable root SSH login, configure fail2ban rules for both SSH and ERPNext's login endpoint, and set up automatic security updates with
unattended-upgrades. - Set up a staging clone -- Before any major upgrade, clone the site to a staging server with
bench restorefrom a production backup, run the upgrade there, and only then touch production. - Explore the Frappe app ecosystem -- Browse frappe.io/apps for Helpdesk, LMS, Builder (no-code website builder), Drive (file storage), and Gameplan (team chat).
Need a VPS sized for ERPNext?>
Our CloudCore Business plan is specifically sized for self-hosted ERPNext workloads and gives you comfortable headroom for 20-30 concurrent users, a database in the tens of GB, and nightly backups kept on-disk.>
- 4 vCPU cores
- 8 GB RAM
- 100 GB NVMe SSD
- Unmetered bandwidth at 1 Gbps
- Ubuntu 24.04 LTS ready to go
- Root access and full console>
Deploy Your CloudCore Business VPS -- From EUR 24.99 / month, provisioned in under 60 seconds.