A full manual installation guide for ERPNext 13, using VPS + Debian 11. main image

Table of contents


ERPNext is a free and open-source integrated Enterprise Resource Planning software developed by Frappe Technologies Pvt. Ltd. and is built on MariaDB database system using Frappe, a Python based server-side framework. ERPNext is a generic ERP software used by manufacturers, distributors and services companies. Wikipedia

Installation instructions

Here we are using digitalocean Debian 11 droplet ($5/month)

Quick notes

We are going to use these emojis

  • πŸ–₯️ refers to you server IP address

  • πŸ‘€ refers to your user name

  • πŸ§‘πŸ½β€πŸ€β€πŸ§‘πŸΎ is the group name your user belongs to.

    It mostly is the same name as the πŸ‘€

  • πŸ”‘ is the password you’ll use with various settings.

    You can generate a strong password for this with the command openssl rand -hex 8

    Don’t forget to save it somewhere safe

  • 🌍 is your website domain (Or subdomain)

Text editor

I personally prefer vim over nano but you can use whatever text editor you want.

So If you see (Edit some_file), You need to do vim some_file or nano some_file

System Update

  • Login as root to your server IP
  ssh root@πŸ–₯️
  • Add unstable repo to be able to install some dependencies we’ll need later
echo 'deb http://ftp.uk.debian.org/debian/ unstable non-free contrib main' >> /etc/apt/sources.list
  • Now update your system with
apt update && apt upgrade -y

Adding a new user

  • First create a new user with a password (You can use the πŸ”‘ you generated before)

    This command is interactive

adduser πŸ‘€
  • Copy authorized keys to the new user home directory
cp -r /root/.ssh/ /home/πŸ‘€/.ssh
  • Change ownership to the new user
chown -R πŸ‘€ /home/πŸ‘€/.ssh
  • Logout then login again to the new user account:
ssh πŸ‘€@πŸ–₯️

Configuring SSH

  • Modify /etc/ssh/sshd_config: (Use nano or vim)

    Search these options and modify them

    • Use different port (Optional but recommended to reduce brute force attacks) Careful here: If you choose a different port other than the default 22, Remember to allow it in firewall settings in the next section, or else you won’t be able to login with SSH
      • Port 1234 # Or any number 1-65535
    • Disallow root login (highly recommended)
      • PermitRootLogin no
    • Disable login with password (Optional but recommended to reduce brute force attacks)
      • PasswordAuthentication no
  • Finally, restart SSH server with
sudo systemctl restart ssh
  • Now logout then login again

    Note If you configured a new port, you’ll use that port while connecting as follows:

    ssh -p PORT πŸ‘€NAME@πŸ–₯️
  • Add .local/bin/ to path:
    echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
    • If you installed and using ZSH:
    echo 'export PATH=$HOME/.local/bin:$PATH' >> ~/.zshrc

Firewall configurations

  • Install with sudo apt install ufw.
  • Allow SSH, 80 and 443 ports using these commands:
sudo ufw allow ssh # Or the new port you chose above (e.g: sudo ufw allow 1234)
sudo ufw allow nginx
  • sudo ufw enable
  • Check if it’s working with sudo ufw status

Setting up locale

echo "LC_ALL=en_US.UTF-8" >> /etc/environment
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen
echo "LANG=en_US.UTF-8" > /etc/locale.conf
sudo locale-gen en_US.UTF-8

Install basic required dependencies

sudo apt install git python3-dev python3-setuptools 
python3-pip virtualenv nginx wkhtmltopdf redis-server
  • Make sure python3 is the default by typing python --version.

    If it’s not:

    • Delete the old one which is probably just a symbolic link to python2 in this case.
sudo rm /usr/bin/python
  • Create a new symlink
sudo ln -s /usr/bin/python3 /usr/bin/python

Installing Node.js via NVM

  • Use nvm following official guide

  • Install node.js

    Check the required node version for erpnext branch (In the time of writing this document, it is recommended to install version 14)

nvm install 14

Installing MySQL

sudo apt install mariadb-server libmysqlclient-dev
  • Setup mysql
sudo mysql_secure_installation
  • Edit /etc/mysql/my.cnf to add the following lines

    If these sections [mysqld] and mysql exist, Type below them respectively

    Note You may find those sections in other file in /etc/mysql/ so you’d better use something like grep to find them so you can add the code below.

character-set-client-handshake = FALSE
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci

default-character-set = utf8mb4
  • Add mysql user
mysql -u root -p
  • Type these commands
CREATE USER πŸ‘€@localhost IDENTIFIED BY 'πŸ”‘';
GRANT ALL ON erpnext.* TO 'πŸ‘€'@'localhost' with grant option;
  • Restart mysql
sudo systemctl restart mariadb

Installing ERPnext

sudo mkdir /srv/www
sudo chown -R πŸ‘€:πŸ§‘πŸ½β€πŸ€β€πŸ§‘πŸΎ /srv/www/ # Remember UserName:GroupName
cd /srv/www/
pip3 install frappe-bench
heck if bench installed by running `bench --version
bench init frappe-bench
cd frappe-bench
bench new-site 🌍 # Your website domain (Do you feel dizzy yet?)
bench get-app erpnext
bench --site 🌍 install-app erpnext
sudo apt -y install supervisor

Configuring ssl

Generating certificates manually

Browser will show it’s not trusted site, so you’ll need to use it behind cloudflare CDN

  sudo mkdir -p /etc/letsencrypt/live/🌍/
  # Replace "πŸ›οΈ" with your company name (No whitespaces)
  sudo openssl req -x509 -sha256 -nodes -newkey rsa:2048 -days 3650 
  -subj "/C=US/ST=Oregon/L=Portland/O=πŸ›οΈ/OU=Org/CN=🌍" 
  -out /etc/letsencrypt/live/🌍/fullchain.pem 
  -keyout /etc/letsencrypt/live/🌍/privkey.pem
  • Edit sites/🌍/site_config.json.

  • Add those two lines.

    "ssl_certificate": "/etc/letsencrypt/live/🌍/fullchain.pem",
    "ssl_certificate_key": "/etc/letsencrypt/live/🌍/privkey.pem",

Setup production

sudo $HOME/.local/bin/bench setup production πŸ‘€
sudo $HOME/.local/bin/bench setup lets-encrypt 🌍

Updating ERPnext

sudo $HOME/.local/bin/bench update --reset
sudo $HOME/.local/bin/bench migrate

Disable maintenance mode by editing sites/common_site_config.json and set maintenance_mode to 0

Common issues

Check if all services are running

sudo supervisorctl status

supervisor.service cannot restart

You can always check system logs with sudo journalctl|grep supervisor, In my case I found it missing section [supervisord] in ini! So the solution would be adding these sections in /srv/www/frappe-bench/config/supervisor.conf and restart the service



port =

supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

Also Check /srv/www/frappe-bench/config/supervisor.conf for None values and replace it with the bench path command -v bench which most likely will be /home/πŸ‘€/.local/bin/bench.

Don’t forget to sudo systemctl restart supervisor.service.

  • If you encounter a problem with redis port

    Modify redis port in /etc/redis/redis.conf

  • Any time you see this message Your system is being updated. Please refresh again after a few moments in your website, it means the maintenance mode is active.

    To disable it you need to edit sites/common_site_config.json and set maintenance_mode to 0

  • Socketio error (connection refused)

    Check /socket.io in /srv/www/frappe-bench/config/nginx.conf .. Update proxy_pass to used http://localhost:9000 Update this section in /srv/www/frappe-bench/config/supervisor.conf

; Check where your node is installed, in my case it is in (/home/πŸ‘€/.nvm/versions/node/v14.18.1/bin/node) so I'm going to use it in the next line πŸ‘‡πŸΌ
command=/home/πŸ‘€/.nvm/versions/node/v14.18.1/bin/node /var/www/frappe-bench/apps/frappe/socketio.js

Related topics