FOSS ERP - Setting up and playing around with ERPNext
Local setup with the manual installation option and some playing around with ERPNext.
Hey there! Imagine you have a small retail business and its the busy season of the year. You would probably like a system that keeps track of and helps to plan the goods on stock, your sales, no. of employees and their assignments, the expenses you have etc. This is what an ERP, Enterprise resource planning system does. It tracks and helps you plan your flow of goods, value, the usage of your capital etc.. Technically its a transactional system designed for OLTP, that is industry jargon for online transactional processing. A system designed for concurrent inserting and updating data in mostly relational databases. In my other blog posts I was playing around with SAP BW an OLAP, or online analytical processing system. In contrast to the OLTP an OLAP system is designed for complex queries to a huge number of records and mainly read access. OLTP systems are built for a balanced read/write access scenario to a small amount of data.
Certainly one of the best known solutions for an ERP is SAP’s S/4HANA. But for a small business or startup this might be prohibitively expensive. Enter the free and open source [FOSS] ERPs. There are several solutions out there, see here for an overview, but I am going to set up and play around with ERPNext today. Why? Because it has a pretty active community with ~416 contributors, 10.3k stars and 935 releases on github. Also it is web based, i.e. accessible via the browser and built on python which I know and like.
Benefits of an ERP system
An ERP system is a digital twin of all major company processes, or at least that’s what it should be. Theses processes depend on the company’s industry, e.g. a retailer does not have a plan-to-produce process since all products are procured. Often the most important processes are
- Order-to-cash, all the steps necessary from ordering of a product until the customer has paid the product
- Purchase-to-pay, all process steps from purchasing a product until its paid by the company
- Plan-to-produce, all the steps that manufacturing companies need to produce a product
- Financial Management, especially accounting, i.e. keeping track of all the monetary flows and assets between all the accounts of a company
Now its not necessary to use an ERP software for all theses processes. One can certainly do with several specialized solutions e.g. for accounting or even with spreadsheets. The main benefit of such a software is that it integrates and consolidates all the information in one data model and hence serves as a consistence “source of truth”. Often theses systems come with template processes and data models to get you started quickly. The downside of all this is that customization is often expensive and hence at least for small companies the recommendation that I often read is to only customize the solution when absolutely necessary.
Setting up ERP Next
I will set up ERP Next on my local machine on a Ubuntu 20.04 VM. I will use the manual installation, there is also a dockerized solution, a easy install script and prebuilt VMs available. Also note that you can order ERPNext as Software as a Service from their homepage. The you will not have to bother about the set up at all. For the manual installation I follow the excellent guide here.
Prerequisites to follow along
- A Hypervisor , e.g. Oracle’s VirtualBox; for production on bare metal you could e.g. use proxmox.
- Vagrant - not strictly necessary but who doesn’t like infrastructure as code
- Vagrant file, e.g. the one I created here
Setting up the VM
Place the vagrant file in a suitable location. The file specifies the box, i.e. the OS image for the VM, defines names, the network and installs some dependencies of ERPNext. Lets have a closer look:
# encoding: utf-8
# Variable definition
VAGRANT_BOX = 'generic/ubuntu2004'
VM_NAME = 'ERPbox2'
# VM User — 'vagrant' by default
VM_USER = 'vagrant'
# path of folder that should be synced, if any
HOST_PATH = 'F:/virtualbox/ErpNext'
# Where to sync to on Guest — 'vagrant' is the default user name
GUEST_PATH = '/mnt/erpnext'#
VM_PORT = 8080
Above I define some variables that will be used in the body of the script that invokes the VM. VAGRANT_BOX is the name of the VM image from Vagrants image repository, VM_PORT is the host port that I will map the VM port to. The HOST_PATH is the path of the host directory that is mounted to the VM under GUEST_PATH. Mounting a local directory is needed if you want to persist data even when destroying the VM. Per default vagrant mounts the Project Directory to /home/vagrant which I disable below.
Vagrant.configure(2) do |config| # Vagrant box from Hashicorp
config.vm.box = VAGRANT_BOX
# Name of Machine
config.vm.hostname = VM_NAME # Set VM name in Virtualbox
config.vm.provider "virtualbox" do |vb|
vb.name = VM_NAME
vb.memory = 4096
vb.gui = true
end
# Port forwarding
config.vm.network "forwarded_port", guest: 80, host: VM_PORT
# Sync folder
config.vm.synced_folder HOST_PATH, GUEST_PATH
# Disable default Vagrant folder, use a unique path per project
config.vm.synced_folder '.', '/home/'+VM_USER+'', disabled: true
# install dependencies of ERPNext
config.vm.provision "shell", inline: <<-SHELL
apt update
apt upgrade
apt install -y git curl
curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -
apt install -y nodejs mariadb-server redis-server python3-pip nginx python3-testresources python3-distutils python3-setuptools libssl-dev wkhtmltopdf
SHELL
config.vm.provision "shell", path: "erpnext_provisioning.sh"
end
The body of the script defines everything needed to provision the VM. The configuration is written in ruby and is hence very flexible. E.g. with a loop you can provision multiple VMs. The various configuration options can be found in the vagrant docs
In short: I tell vagrant to use virtualbox as provider and configure the name of the VM and allocate 4GB of memory to it. I set the gui to true, which opens the virtualbox console. This is handy if you have never worked before with the box and want to see what it does during startup. Some boxes require you to input something during installation which is hard to diagnose without the gui. I forward port 80 to the host port 8080, mount the local folder and finally install some dependencies of ERPnext.
In config.vm.provision “shell”, inline: «-SHELL I use the shell inline provisioner to execute tasks in the VM shell. Here I could also use ansible playbooks, something that I definitely want to explore.
First I update the VM with apt update and upgrade, then I install curl and node.js from source in version 14. I also need:
- mariadb-server: The relational database ERPNext stores data in
- redis: in-memory Caching-layer
- nginx: Webserver
- libssl: Library for Transport Layer Security, not strictly needed here since I will not create certificates for my local play environment
- wkhtmltopdf: HTML to PDF converter
Find the dependencies of the frappe framework also here
Just for fun I use a second way to execute shell commands by passing an external file. in erpnext_provisioning.sh which is in the same folder, I create a new user and configure the mariadb:
Find the file also here.
#!/bin/bash
# create ERP user
adduser erpnext --gecos "" --disabled-password
usermod -aG sudo erpnext
# Append MYSQL Conf to file
cat <<EOT >> /etc/mysql/my.cnf
[mysqld]
character-set-client-handshake = FALSE
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
[mysql]
default-character-set = utf8mb4
EOT
vagrant up
starts the VM. A virtualbox window should open where you can follow along the provisioning process if your host has graphical output.
vagrant ssh
The command above will attach a shell to the default VM, provide the name of the ERPnext VM with vagrant ssh [name|id] if you have many VMs, you can get a list and the status of your VMs with vagrant status.
Additional work after VM provisioning
I will do the remaining setup from within the VM. These steps can probably be automated in a script as well.
In the shell I make myself root and set a password for the ERPNext user:
sudo su -
passwd erpnext
from here on I basically follow the tutorial created by bkm in the ERPNext forum, here
restart the database:
service mysql restart
set up the database:
mysql_secure_installation
- Set root password? [Y/n]: y
- Remove anonymous users? [Y/n]: y
- Disallow root login -remotely? [Y/n]: n
- Remove test database and -access to it? [Y/n]: y
- Reload privilege tables -now? [Y/n]: y
Login to mariadb:
mysql -u root -p[your-password-here]
and execute the following in the mysql CLI:
USE mysql;
UPDATE user SET plugin=' ' WHERE user = 'root';
FLUSH PRIVILEGES;
exit
Change to the erpnext user:
su erpnext -
and install yarn and frappe bench
sudo npm install -g yarn
pip3 install frappe-bench
export PATH=$PATH:/home/erpnext/.local/bin
sudo pip3 install frappe-bench
setup bench for production, this will configure nginx and create the services needed to run automatically after restarting the VM
cd /mnt/erpnext
bench init --frappe-branch version-13 frappe-bench
cd frappe-bench
bench new-site site1.local
bench get-app --branch version-13 erpnext
bench --site site1.local install-app erpnext
sudo bench setup production [USER]
The I have to check whether the supervisor.conf file was created in /etc/supervisor/conf.d.
In my case it was not so I had to copy it from the frappe directory:
sudo cp ~/frappe-bench/config/supervisor.conf /etc/supervisor/conf.d/supervisor.conf
Now the last step is to enable the scheduler and reboot:
bench --site site1.local enable-scheduler
sudo shutdown -r now
A running ERP instance
And finally a running ERP on localhost:8080:
Next steps
Now the hard part is setting up and configuring the ERP from scratch. I certainly want to play around a little and setup some test processes. Stay tuned.