Cloud Hosted ERPNext & Local Printers(USB/Network) [WIP]

This is a documentation post of an ongoing research we are executing to implement a mechanism to manage and use multiple printers across multiple locations. The setup needs to work with an ERPNext instance that is hosted on the cloud.

The intention of this post is to document our journey, potential solutions we come up with and possible issues we face. We also hope to get inputs and feedbacks from others in the community who have nailed this with lesser firepower. As many of you, we too at times over-engineer.


We had previously discussed about a quick hack that worked for us in a scenario that was less complex in a conference talk.

Our current use-case is for a restaurant chain, with multiple branches. In each location, we will be having multiple POS machines & mobile phone which will initiate actions that send prints to multiple printers.

Some of it will be network printers. Currently in ERPNext, we can easily print invoices, bills etc… via browsers print option, as long as the printers are available in it. However this only works for user initiated printing. The limitations are:

  1. No option to logically route print to a particular printer. (For example, a specific kitchen based on item)
  2. No option to execute background print. (For example KOT against online order)
  3. No option to execute multiple prints. (Bill at counter & KOT at kitchen)

Though 3rd point was partially solved in the video shared above, it doesn’t really work in a multi-branch scenario.

Before we go into various solutions we explored, I recommend you look at how it was done in a single location with the help of flask in the link provided.

On top of all this, we also can’t pick a solution that charge per ip, location or printers. There are some paid solutions that solves some of our challenges.

Scenario 1:
Best possible outcome would have been ERPNext/Frappe directly sending prints to prescribed printers as shown in the diagram below. Let us call this Scenario 1. While this is technically possible with most printers that support IPP, in real-world it is almost impossible to achieve without some proxy servers in between.

Challenges for scenario 1

  • Requires a dedicated-ip or domain via which we can connect to the printer. Port also need to be forwarded. While many ISP does give this, it is not something we can expect in every QSR branch. And this definitely is not a complete solution if it involves talking to ISP.
  • Solutions like no-ip doesn’t work in most ISPs as ports are not forwarded by default. You need to raise a request with the ISP to see if it works for you.
  • Even if you get a dedicated-ip and the port. Our setup will still fail, in case we use a mobile hotspot for internet due to an outage. Almost all our clients, do fallback to mobile network few times a month.


Scenario 2:
The next best possible solution is to proxy all print requests initiated on ERPNext to a client system at the local network and let that machine push it to the printer.

Here, the printer & client connection part is trivial. However, finding a way for server to let the client know when a print job is created is the tricky part.

We figured out two ways to get this done:

  1. Expose a flask/node app via a tunnel using some solution as ngrok. That way the issue of ip is resolved. Then that flask application can initiate the print just as we did in the video linked in this post before.
  2. Make use of Frappe’s realtime support using web-socket. We were able to send print request via web-socket to POS & other relevant front-ends this way. Then the front-end as in the KOT solution in the video above, will make a request to the flask app running locally.

If we can somehow connect to Frappe via web-socket directly from the flask application, then we can avoid having to use the POS or other front-end page to be the means to receive prints. Relying on front-end page will be error prone and is not very reliable. For example, you can loose prints if the user closes the tab or is refreshing the tab when a print comes.

There is a query on this in Discuss here. This is the python client library that we could potentially use to interface with Frappe/ERPNext web-socket server. We’ll explore this when we get time.

Another backup plan is to, maybe have this run in a headless browser initiated via python and listen in to the socket from it.

A rough diagram of how the whole websocket based solution could work is outlined below:

In frappe, we plan to create few doc types such as:

  • Printer (add printers, location/branch, ip or domain, status)
  • Print Queue (print jobs are added here along with the destination printer info)

Any application that need to send a print to a printer without the user initiating it, needs to create a document in the queue along with the destination printer. Ideally we will need to get a feedback if the print succeeded and also have some mechanism to retry.

Some other observation:

  • Configuring different printers on the system is often tricky and vary from printer to printer. We have found using network printer along with IPP to be the best option if you plan to maintain a consistent solution without having to deal with proprietary drivers and their headaches.
  • Using CUPs for connecting to printer can help streamline this process. We where able to use cups via docker in windows based machine as well.

Do let us know if you have solved any issue as this. Or if you have any suggestions.


  • We had success using network printing suggested by @mujeerhashmi along with cloudflares tunnel. We had to use tunnel to reach to local branches that doesn’t have a static ip or port forwarding.
  • We are also checking based solution that @ankush suggested over telegram.

Network Printers are already supported in ERPNext. Check this out ( I have not tested it though.

1 Like

We have an implementation in the wild like this. It is a CUPS server that’s on prem, the Frappe server is in the cloud. Some development on the Network Printer Settings doctype was required, but this allowed us to print barcode labels with the click of a button.


This is a very good topic about network printing, and in fact, there are many similar practices in China. For example, Taobao and Pinduoduo, these giant e-commerce companies, need to print a lot of logistics waybills during the process of conducting e-commerce business. They use the service layer → middleware service → printer architecture that you mentioned. The middleware service is important and usually requires the installation of a guardian process. It is generally installed on Windows and serves as a client for WebSocket.

A similar middleware can be referenced here: GitHub - dandanhuiyi/printer: 测试 web 页面调用 菜鸟打印组件 和 Lodop打印组件

For this business scenario, there are actually two design approaches:

  1. The middleware service needs to be developed as a client by Frappe. This is usually done for the Windows version. However, I don’t recommend using WebSocket, but I highly recommend using Socket.IO. Socket.IO and Frappe’s Socket.IO are two different forms of socket connections, and I suggest using Socket.IO + Frappe’s Socket.IO.
  2. The second approach is to use some public middleware services. For Frappe or ERPNext, Lodop or other printing components can be used. You need to send PDF or HTML to these ws:// endpoints.

I’m really looking forward to seeing Frappe’s improvement in this area.

1 Like

@esafwan I’m shortly before introducing the ERPNext and looking also very intensive for a proper cloud-print solution and didn’t find until now.
I know from other ERP solutions a comparable simple, robust and reliable solution:

Raspberry Pi with cups and a little webserver application which connects via API to the ERP instance and listen if a print job is open. I don’t understand why ERPNext is not having such a little “helper” software.