[Tutorial] How to 'manually' install ERPNext v13.11 Production on Debian 10 (w/SSL cert)

EDIT 12-22-2021 BKM
Edited the text of the procedure to include a check for the supervisor.conf file. At some point in the past 2 weeks, this Tutorial was not producing a complete system. Something changed and the supervisor.conf file was no longer being dropped into the proper directory to allow the system to boot to a login screen. this meant that you could not run the startup wizard with the first login of the Administrator. While I was not able to track down the source of the problem yet, I have included a few additional steps before enabling the scheduler to check for this error and fix it before completing the install. The procedure begins below. Hope this helps. :nerd_face:

Here is how to do this manually. It is not the ONLY way to do it and this method does have some peculiar things about it (like installing bench twice) but it works and it works very well. You also do not get the bench editable mode messages with this method.

One more thing to note before you start. You may have heard all kinds of things about having to rename the bench and renaming site directories to make your URLs work, etc. Well, this install method, if followed exactly, produces nearly an identical installation as you would have done using the old Easy Install script. That means that you will be using bench commands to define your sites and not brute force renaming of directories and other nonsense. This method really simplifies everything. So, now go ahead and get started. :grin:

Read every line carefully. Don’t skip any steps!

Anywhere that you see [USER] you need to insert your server user name.

  • Choose any cloud you trust

  • Login to your system via ssh with root user (I use putty client for this)

  • apt update && apt upgrade -y && shutdown -r now

  • Log back in as root user again then type the following commands:
    apt-get install curl git
    apt-get install sudo
    curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -

  • Now we install all of the prerequisites for a functioning server:

apt install -y nodejs mariadb-server redis-server python3-pip nginx python3-testresources python3-distutils python3-setuptools python3.8-venv libssl-dev wkhtmltopdf

  • Now add the user to serve as the home directory for the ERPNext install:

adduser [USER]
usermod -aG sudo [USER]

  • Now we need to edit the MySQL config file:
    nano /etc/mysql/my.cnf
    When the editor opens scroll to the bollom of the file and add these lines:

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

default-character-set = utf8mb4

  • Now we need to restart mysql:
    service mysql restart

  • Here we setup mysql (mariadb) to operate properly:
    (press the enter key for password then answer the questions as follows)
    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

  • To complete the mysql setup do the following:
    mysql -u root -p[your-password-here]
    Immediately after the -p type the password you assigned to mariadb in the last step. Remember there is to be NO space between the -p and the first character of the password. Then at the database prompt type the following commands (case sensitive & press enter after each line)
    USE mysql;
    UPDATE user SET plugin=' ' WHERE user = 'root';

  • Close the terminal window (logout of root) and open a new one with ssh [USER] and execute the following commands:

sudo npm install -g yarn

pip3 install frappe-bench
export PATH=$PATH:/home/[USER]/.local/bin

sudo pip3 install frappe-bench

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]

Now, due to recent problems it is important to check for the existence of an important configuration file. Execute the following command:

sudo ls /etc/supervisor/conf.d

If supervisor.conf is listed as a file here, then you can skip to the ‘enable scheduler’ step below. However, If there are no files listed then the supervisor.conf file was not transferred properly. To fix this perform the following command:

sudo cp ~/frappe-bench/config/supervisor.conf /etc/supervisor/conf.d/supervisor.conf

This should fix the problem of not being able to get to the login screen. :nerd_face: You can now finish the rest of the install.

bench --site site1.local enable-scheduler

  • Now reboot the server. Once it has rebooted you should be able to open a web browser and type in the ip address of your server to get the ERPNext login screen. Login as administrator and go through the setup wizard before attempting to do any further work on the server. Once that is done come back to this point to continue setting up your URL and your SSL certificate (very simple to do)!

  • Once you have complete the Administrator setup wizard, log out of ERPNext and open a fresh SSH window and login as [USER] then execute the following to add your URL to your ERPNext Server installation:
    export LC_ALL=C.UTF-8
    cd frappe-bench
    bench config dns_multitenant on
    bench setup add-domain --site site1.local [your.new.URL]
    bench setup nginx (answer Y to the question about replacing the config file)
    sudo service nginx restart
    cd ~

  • Now it is time to work on the SSL certificate for your server. First we need to make sure that certbot is not already installed:
    sudo apt-get remove certbot

  • Now we are going to install the package bundle provider and make sure it is all up to date with the latest release of ‘snapd’ and let it handle the certbot for us (much simpler this way):
    sudo apt install snapd
    sudo snap install core
    sudo snap refresh core

  • Now we use the ‘snap’ service to automatically install and configure certbot to work properly with your new ERPNext server:
    sudo snap install --classic certbot
    sudo ln -s /snap/bin/certbot /usr/bin/certbot

  • Now we can safely use the pre-configured certbot to install your SSL certificate:
    sudo certbot --nginx
    (The system will pause at some point and ask you to select the site name you wish to install the certificate from a list of names it found. Be sure to select the URL you used and not ‘site1.local’ at this point)

  • Once this is done, you can close your ssh client, open a browser and type the URL of your server into the address bar and it should take you to the secured version of your ERPNext server.

  • One final note here. This method specifically does NOT rename bench or the site directories in order to provide flexibility later in the event you need to have multiple URL’s pointing to the same instance of ERPNext or if you need to change your URL for some reason in the future. Using the bench setup add-domain command makes this much simpler. The SSL certificate instructions I provided above are tailored to support this configuration.

Hope this helps, but as always…

Your mileage may vary :sunglasses:



Hi. yesterday I tested the core easy install script on 2 different Ubuntu 20 servers. It worked flawlessly. Didn’t need to do any manual intervention Only change was the final command which was

sudo python3 install.py --production --user [new user] --version 13 --site [erp.abc.com] --mysql-root-password [password] --admin-password [GUI Admin Password] --verbose

sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt-get install python3.6

Run above 3 commands before wget of install.py

As a precautionary measure run this command on fresh server before running the final above command export LC_ALL=C.UTF-8

1 Like

@bkm thanks for the new tutorial, we tried this on a production environment and have noticed that when you are sending out a quotation from erpnext and have used the site1.local as the parameter name on your site, for instance, you mentioned the commands below.

  • List item bench new-site site1.local
  • List item bench --site site1.local install-app erpnext
  • List item bench --site site1.local enable-scheduler

The link by default goes like http://site1.local/Quotation/SAL-QTN-2021-00001
So when the user clicked on the view on the browser link (screenshot attached), the link becomes invalid.

I assume it is the command ‘bench --site site1.local enable-scheduler’ that affects this?
Please confirm, thanks in advance.


install was going well untill…
bench init --frappe-branch version-13 frappe-bench
I am getting…
[Errno 13] Permission denied: ‘frappe-bench’
ERROR: There was a problem while creating frappe-bench
Do you want to rollback these changes? [y/N]:

Any ideas?

I guess you skipped this step:

1 Like

Just used @Muzzy install method and now get:

PLAY RECAP *********************************************************************************************************
localhost : ok=88 changed=52 unreachable=0 failed=0 skipped=59 rescued=0 ignored=0

Bench + Frappe + ERPNext has been successfully installed!

should I now be able to access on my www.[123].com?

Hello @bkm

I incorrectly posted this in the previous “easy” install script, but re-post it here in the correct topic.

Thanks so much for your ongoing focus on helping to install ERPNext.

I followed your instructions to the tee. However, I get errors when “install-app erpnext”. The error has to do with “cannot import name ‘clear cache’”. I fear it has something to do with Python vesions. The latest Debian 10.11 bundles Python 3.7, rather than 3.6 which is known to work. Do you know which minor version of Debian 10 had Python 3.6. We can then select the correct Debian iso from https://cdimage.debian.org/mirror/cdimage/archive/

Kindest regards

Further to my above comments, I’ve uncovered that Debian 10 bundled Python 3.7 ever since Debian 10.0. So it cannot be the Python version which causes the following errors.

1 During the bench get-app --branch version-13 erpnext command I get the following error

ERROR: pip’s dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
frappe 13.16.0 requires PyJWT~=1.7.1, but you have pyjwt 2.3.0 which is incompatible.

However, the command continues and a bit later the following warning

Browserslist: caniuse-lite is outdated. Please run:
npx browserslist@latest --update-db
Browserslist: caniuse-lite is outdated. Please run next command yarn upgrade caniuse-lite browserslist

The command then finishes successfully.

2 I then invoke the following command bench --site site1.local install-app erpnext

This command immediately terminates with this error

Module import failed for Payment Request (erpnext.accounts.doctype.payment_request.payment_request Error: cannot import name ‘clear_cache’ from ‘frappe.website.utils’ (/home/unmeep/frappe-bench/apps/frappe/frappe/website/utils.py))

Any help would be much appreciated as I (and I presume all of us) now have no way of installing ERPNext other than the Docker method.

Did you follow the suggested fix:

These suggestions are usually the correct path to getting things to work. At this point is has been just over 2 months since I have had to do a fresh install. During the coming weekend break I will revisit this instruction set to see how is it holding up.


Hello @bkm

Oh certainly, I tried every suggestion and also the recommendations on this forum:

1 I have no idea of what to do about the PyJWT incompatible versions. There are many forum topics about this but they are 2 to 3 years old.

2 I applied the 2 recommendations in both orders, and in both cases it succeeds, however it has no impact on the latter error.

3 The “cannot import name ‘clear_cache’” error has come up frequently in the past few days, and there are at least 5 forum topics on it, however, and sadly so, no second post to shed any light on the issue. The only glimmer of hope was from a post by @Suresh_Thakor in Error when running bench "update --patch" after fresh install However this also did not alleviate the error.

Please try using following command.

bench get-app erpnext GitHub - frappe/erpnext: Free and Open Source Enterprise Resource Planning (ERP) --branch version-13

Thanks @Suresh_Thakor

Your recommendation helped with alleviating the PyJWT error and the command completes successfully, however the caniuse warnings are still present.

I then run bench start but the caniuse issue seems to prevent startup.

06:49:22 watch.1 | Watching…
06:49:22 watch.1 | Browserslist: caniuse-lite is outdated. Please run:
06:49:22 watch.1 | npx browserslist@latest --update-db
06:49:23 watch.1 | Error in: undefined
06:49:23 watch.1 | Error: ENOSPC: System limit for number of file watchers reached, watch ‘/home/unmeep/frappe-bench/apps/frappe/frappe/public/less/variables.less’
06:49:23 watch.1 | at FSWatcher. (internal/fs/watchers.js:243:19)
06:49:23 watch.1 | at Object.watch (fs.js:1586:34)
06:49:23 watch.1 | at new FileWatcher (/home/unmeep/frappe-bench/apps/frappe/node_modules/rollup/dist/rollup.js:37956:33)
06:49:23 watch.1 | at addTask (/home/unmeep/frappe-bench/apps/frappe/node_modules/rollup/dist/rollup.js:37890:36)
06:49:23 watch.1 | at Task.watchFile (/home/unmeep/frappe-bench/apps/frappe/node_modules/rollup/dist/rollup.js:38209:9)
06:49:23 watch.1 | at /home/unmeep/frappe-bench/apps/frappe/node_modules/rollup/dist/rollup.js:38188:39
06:49:23 watch.1 | at Array.forEach ()
06:49:23 watch.1 | at /home/unmeep/frappe-bench/apps/frappe/node_modules/rollup/dist/rollup.js:38187:58
06:49:23 watch.1 | at Array.forEach ()
06:49:23 watch.1 | at /home/unmeep/frappe-bench/apps/frappe/node_modules/rollup/dist/rollup.js:38185:41


I’ve followed the installation step by step until
bench --site site1.local enable-scheduler

and rebooted the server and upon typing the ip adress in the browser, I got the below message:


We will be back soon.

Don’t panic. It’s not you, it’s us.
Most likely, our engineers are updating the code, and it should take a minute for the new code to load into memory.

Try refreshing after a minute or two.

And then ran the command bench start

Then I was finally able to see the erpnext login screen in the browser.

But how can I set erpnext to autostart on server reboot?

@mnabil777 I want to welcome you to the ERPNext community!! It is always good to see new users.

It is unfortunate that you had to encounter trouble while using one of my Tutorials. However, the problem is NOT of your making. It is one that has recently started happening after recent Debian updates.

At this point I do not have an answer.

I have also been struggling with this very same issue since Friday of last week. I have a friend that jumped in to help after I had struggled for 3 days trying to get a working server. He explained that for some reason the Supervisor was not running.

It should have started with the command:

sudo bench setup production [USER]

However something failed that had previously been working just fine.

The clue to this was found by running the following command:

sudo lsof -nP -iTCP -sTCP:LISTEN

The results indicated that no tasks were listening on port 8000, 11000, 12,000 or 13,000. With Supervisor not running then Redis and ERPNext do not launch.

The fix for my server was to copy a configuration file from the ERPNext configs directory to an appropriate location and restart Supervisor. (Again I do not have the exact details for this).

Please understand, I did not fix this myself. I had to call in help so I could get a test server active to allow me to test a new app that I had been waiting for this week. I am not familiar with the details of the fix.

I will try to work on how to avoid this after the holidays. I believe it has something to do with recent changes to the Debian 10 sources.

For now, I am extremely busy testing this new app and working out how to implement it for the first week of January. So, I do not have time to dig deeper into the source of the failure.

Hopefully I have provided enough information here that someone else might have time to investigate. If not, then I will try to get to it in mid-January once I have meet my current and urgent contractual obligations.

I am sorry that I do not have any additional information to share at this time. I was fortunate enough to have a good friend, that is also quite busy at this time, and he was able to give me a few minutes of his time to get my server running. I hope to work with him again when both our schedules quiet down sometime after the holidays to track down the source of the problem and possibly a way to avoid it in the future.

Thank you for further confirming that the errors myself and others have encountered are running across multiple VPS services and not just the one I was using.



Thanks a lot for the warm welcome and for your help. I would be eagerly awaiting your advise regarding this when you’re available.

However, in the meantime, since I’m new to Frappe and ErpNext, I would like to understand the complete architecture of Frappe form a technical & implementation perspective.

I come from a technical and programming background. Have been in the infrastructure, software development & ERP consultation & deployment for the past 15 Years.

Hence, would like to request if you could guide me in the right direction & resources to understand the basic technical architecture of this and how this works. For eg. how can I spin up multiple instances of erpnext on the same server etc.


Simply do a search of the forum for the topic: “Multitenant” or “Multi-tenant”

It is a method of hosting multiple ERPNext instances from a single installation. I have used it to host 5 or 6 individual kiosk businesses from a single VPS server with no issues.

But this thread is really for installing ERPNext for the first time and getting it running with little or no troubles. So, for now, I need to find the current trouble in my tutorial and get it corrected to match the new Debian updates.

If you want to ask questions about other topics kindly open new topic threads. You would be surprised how helpful the community can be.


@mnabil777 I wanted to let you know that after a few minutes of experimenting this morning, I have found a way to make the install work again. I have already edited the procedure at the top of the thread to include the fix for not being able to get to a login screen (and not really getting to anything that looked like ERPNext).

Some process that is part of the sudo bench setup production [USER] step was not properly placing a configuration file in the right place. I have added steps to check for the file and then copy it to the right location if it is not already done.

This should take care of the problem you were facing and it will allow the system to run without having to always run the bench start command.


Generated an error about accounting closing vouchers (Module import failed for Period Closing Voucher (erpnext.accounts.doctype.period_closing_voucher.period_closing_voucher Error: cannot import name ‘clear_cache’ from ‘frappe.website.utils’ (/home/frappe/frappe-bench/apps/frappe/frappe/website/utils.py))
). So we issued:
bench uninstall-app erpnext
bench get-app erpnext https://github.com/frappe/erpnext --branch version-13

We’ve also faced this error:
frappe 13.17.1 requires PyJWT~=1.7.1, but you have pyjwt 2.3.0 which is incompatible.
We solved it by
pip3 install -U PyJWT==1.7.1

i am getting following error while using your step-

TASK [bench : python3 bench init for production] *********************************************************************************************
task path: /tmp/.bench/bench/playbooks/roles/bench/tasks/main.yml:44
<> EXEC /bin/sh -c ‘echo ~root && sleep 0’
<> EXEC /bin/sh -c ‘( umask 77 && mkdir -p “echo /var/tmp”&& mkdir /var/tmp/ansible-tmp-1640363489.6695516-42545-235599272452764 && echo ansible-tmp-1640363489.6695516-42545-235599272452764=“echo /var/tmp/ansible-tmp-1640363489.6695516-42545-235599272452764” ) && sleep 0’
Using module file /usr/local/lib/python3.8/dist-packages/ansible/modules/commands/command.py
<> PUT /root/.ansible/tmp/ansible-local-39163vuwgm1u9/tmpuhmlm5e6 TO /var/tmp/ansible-tmp-1640363489.6695516-42545-235599272452764/AnsiballZ_command.py
<> EXEC /bin/sh -c ‘setfacl -m u:global:r-x /var/tmp/ansible-tmp-1640363489.6695516-42545-235599272452764/ /var/tmp/ansible-tmp-1640363489.6695516-42545-235599272452764/AnsiballZ_command.py && sleep 0’
<> EXEC /bin/sh -c ‘chmod u+x /var/tmp/ansible-tmp-1640363489.6695516-42545-235599272452764/ /var/tmp/ansible-tmp-1640363489.6695516-42545-235599272452764/AnsiballZ_command.py && sleep 0’
<> EXEC /bin/sh -c ‘chown global /var/tmp/ansible-tmp-1640363489.6695516-42545-235599272452764/ /var/tmp/ansible-tmp-1640363489.6695516-42545-235599272452764/AnsiballZ_command.py && sleep 0’
<> EXEC /bin/sh -c ‘sudo -H -S -n -u global /bin/sh -c ‘"’“‘echo BECOME-SUCCESS-nkycjnutoqdluwhrypxfexjmuxmxempf ; /usr/bin/python3 /var/tmp/ansible-tmp-1640363489.6695516-42545-235599272452764/AnsiballZ_command.py’”’“’ && sleep 0’
<> EXEC /bin/sh -c ‘rm -f -r /var/tmp/ansible-tmp-1640363489.6695516-42545-235599272452764/ > /dev/null 2>&1 && sleep 0’
fatal: [localhost]: FAILED! => {
“changed”: true,
“cmd”: [
GitHub - frappe/frappe: Low code web framework for real world applications, in Python and Javascript”,
“delta”: “0:00:00.271657”,
“end”: “2021-12-24 16:31:30.158539”,
“invocation”: {
“module_args”: {
“_raw_params”: “bench init ~global/frappe-bench --frappe-path GitHub - frappe/frappe: Low code web framework for real world applications, in Python and Javascript --frappe-branch version-13 --python python3”,
“_uses_shell”: false,
“argv”: null,
“chdir”: null,
“creates”: “/home/global/frappe-bench”,
“executable”: null,
“removes”: null,
“stdin”: null,
“stdin_add_newline”: true,
“strip_empty_ends”: true,
“warn”: true
“msg”: “non-zero return code”,
“rc”: 1,
“start”: “2021-12-24 16:31:29.886882”,
“stderr”: “Traceback (most recent call last):\n File "/usr/bin/bench", line 33, in \n sys.exit(load_entry_point(‘frappe-bench’, ‘console_scripts’, ‘bench’)())\n File "/usr/bin/bench", line 22, in importlib_load_entry_point\n for entry_point in distribution(dist_name).entry_points\n File "/usr/lib/python3.8/importlib/metadata.py", line 503, in distribution\n return Distribution.from_name(distribution_name)\n File "/usr/lib/python3.8/importlib/metadata.py", line 177, in from_name\n raise PackageNotFoundError(name)\nimportlib.metadata.PackageNotFoundError: frappe-bench”,
“stderr_lines”: [
“Traceback (most recent call last):”,
" File "/usr/bin/bench", line 33, in ”,
" sys.exit(load_entry_point(‘frappe-bench’, ‘console_scripts’, ‘bench’)())“,
" File "/usr/bin/bench", line 22, in importlib_load_entry_point”,
" for entry_point in distribution(dist_name).entry_points",
" File "/usr/lib/python3.8/importlib/metadata.py", line 503, in distribution",
" return Distribution.from_name(distribution_name)“,
" File "/usr/lib/python3.8/importlib/metadata.py", line 177, in from_name”,
" raise PackageNotFoundError(name)",
“importlib.metadata.PackageNotFoundError: frappe-bench”
“stdout”: “”,
“stdout_lines”: []

PLAY RECAP ***********************************************************************************************************************************
localhost : ok=65 changed=15 unreachable=0 failed=1 skipped=64 rescued=0 ignored=0

i tried manual method above too , and i get a redissearch module import error in e_commerce module ,
i tried installing redissearch manually and tried again, and still same error .

trying on ubuntu 20.04

It’s failing for me as well on fresh Ubuntu 20 server with python 3.8 error. Try this manual method