How Add nodejs App to frappe & bench?

I need to add nodejs app to use barcode API:

I can run it on port 3030 but I want it to be integrated to the framework while start the erpnext by default .

What the steps are needed to that?

Mohammed Redha

Any help please?

@Mohammed_Redha i dont know how its done but this would be the best example i have seen. GitHub - techmaxsolucoes/bpmn_editor: BPMN Editor for Frappe

Thanks for your reply but this is not what I am looking for.
I want to run nodejs server to consume API call.

How to start nodejs server when bench start?

in development add line to Procfile

custom_app: /usr/bin/node apps/custom_app/custom_node.js

or,

In production add following to supervisor.conf

[program:frappe-bench-custom-app]
command=/usr/bin/node /home/revant/frappe-bench/apps/custom_app/custom_node.js
priority=4
autostart=true
autorestart=true
stdout_logfile=/home/revant/frappe-bench/logs/custom-app.log
stderr_logfile=/home/revant/frappe-bench/logs/custom-app.error.log
user=revant
directory=/home/revant/frappe-bench

[group:frappe-bench-extras]
programs=frappe-bench-custom-app

Refer this gist

Please share if there are any better ways to do this.

6 Likes

Hi @Mohammed_Redha,

Sure, I’ll check and get back to you if i find any issue or find better way.

Thanks.

I have just been experimenting with this and can confirm that is works!

It took a while to pick through the various connections to fully understand what goes on, so as a reminder to myself and to help anyone else trying to get started with this, I have annotated the gist (for development mode)…

I have not tried in production, so I’ve left that “as an exercise for the student”. :smiling_imp:

Some things to notice:

  • the only linking information between the NGinx configuration and the NodeJs app is the port number

  • the only linking information between the NodeJs app and the Frappe configuration is the NodeJs entry-point file path specified in Procfile

  • the name you use in Procfile, (which is custom_app in this example), is the name that appears color coded in Frappe’s log files…

Screenshot_2020-04-14_09-08-33

Screenshot_2020-04-14_09-17-16

It seems as though changes you make to you NodeJs files can only be tested by killing your bench and then rerunning bench start the reloading the browser pages, a long slow pain in the ass. So, if you have a lot of coding and testing to do, it’s going to be better doing it in a separate auto-reloading NodeJs environment.

Update

Something else worth knowing – you can embed the NodeJs app within the directory hierarchy of a Frappe module/app.

So, if you do …

bench new-app library_management

… you’ll end up with:

erpdev@erpdev:~/frappe-bench$ tree -L 1 apps/library_management/
apps/library_management/
├── MANIFEST.in
├── README.md
├── library_management
├── library_management.egg-info
├── license.txt
├── requirements.txt
└── setup.py

3 directories, 5 files
erpdev@erpdev:~/frappe-bench$

Then you can do the following to start your NodeJs apps within it:

erpdev@erpdev:~$ pushd frappe-bench/apps/library_management/
~/frappe-bench/apps/library_management ~

erpdev@erpdev:~/frappe-bench/apps/library_management$ tree -L 1
.
├── MANIFEST.in
├── README.md
├── library_management
├── library_management.egg-info
├── license.txt
├── requirements.txt
└── setup.py

2 directories, 5 files
erpdev@erpdev:~/frappe-bench/apps/library_management$ mkdir -p services/isbn_service
erpdev@erpdev:~/frappe-bench/apps/library_management$ pushd services
~/frappe-bench/apps/library_management/services ~/frappe-bench/apps/library_management ~
erpdev@erpdev:~/frappe-bench/apps/library_management$ pushd isbn_service
~/frappe-bench/apps/library_management/services/isbn_service ~/frappe-bench/apps/library_management/services ~/frappe-bench/apps/library_management ~
erpdev@erpdev:~/frappe-bench/apps/library_management/services/isbn_service$ npm init
This utility will walk you through creating a package.json file.

   :
   :

About to write to /home/erpdev/frappe-bench/apps/library_management/services/isbn_service/package.json:

{
  "name": "isbn_service",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}


Is this OK? (yes) yes
erpdev@erpdev:~/frappe-bench/apps/library_management/services/isbn_service$ popd
~/frappe-bench/apps/library_management/services ~
erpdev@erpdev:~/frappe-bench/apps/library_management/services$ tree -L 2
.
└── isbn_service
    └── package.json

1 directory, 1 file

In this case, because of the changed directory path and because of the main setting in package.json, your Profile would have to read:

   :
   :
isbn_service: /usr/bin/node apps/library_management/services/isbn_service/index.js
   :
   :

Update 2020/05/06:

Node apps typically need to load environment variables and other settings.
It’s worth noting that Procfile will launch any non-terminating script.
So you can do for example:

File apps/library_management/services/isbn_service/do_it.sh:

#!/usr/bin/env bash
#
export BASE_DIR=$(dirname "$(realpath $0)");
cd ${BASE_DIR};
npm run nodemon_start;

where npm can handle pre-launch setups of any complexity.

In which case your Procfile would contain instead:

   :
   :
isbn_service: apps/library_management/services/isbn_service/do_it.sh;
   :
   :
6 Likes

Now it is possible to customize default nginx configuration for containerized setup.

https://github.com/frappe/frappe_docker/pull/442

Hi @revant_one , thank you for keeping track of the issue. I manage to add nodejs App to frappe & bench in development environment.

But I am having trouble with adding nodejs App to k8s setup.
My assumption is that k8s setup does not use supervisor.conf. I can add another nodejs deployment and pod, but that need more config in the nginx-pod or ingress and I don’t think that is the scalable way.

Do you have any pointer in this matter ?

Best regards

add your deployment and related service. use nginx.config in nginx values to override default nginx config.

you can refer what is done for socketio

1 Like

thank u @revant_one for the pointer :smiley: