NodeJS

johannes

Verified User
Joined
Feb 18, 2007
Messages
962
Please can anybody enlighten me, how NodeJS is proposed to work under Litespeed in DA? Maybe @Martynas, please? Litespeed can work as end-proxy for NodeJS according to the LS docu, but in DA docu it calls for a Nginx unit. Should we run Litespeed together with Nginx frontend proxy? And how does it work with the GUI, is the GUI needed at all, will it work only with Nginx unit or also with LS proxy frontend? If not, is there are GUI for LS? Is it possible to setup NodeJS without GUI with LS per user, if yes how? Any enlightment welcome!
 
No you should not run the NGINX unit. Litespeed works automaticly as a proxy via http or via websocket.

Do you run cloudlinux or not?

It is quite easy depending on your OS i can tell you how and what. :)

And yes it works without GUI or with :P It is not so difficult
 
No you should not run the NGINX unit. Litespeed works automaticly as a proxy via http or via websocket.
Thanks, it confirms my thoughts after reading the LS docu.
Do you run cloudlinux or not?
Nope, not anymore, switched to pro pack, was not aware that it doenst support NodeJS for LS out of the box :(
It is quite easy depending on your OS i can tell you how and what. :)
Yesss, please. I must add, that i have a linux admin who does the work on the server. I`d highly like to know your info and forward it to him!
OS is AlmaLinux 8.9, and Litespeed Webserver Pro. (I have another server, till now administering myself, would like to learn it by doing too)
And yes it works without GUI or with :p It is not so difficult
How? Without GUI i thought so, but dont know how. But with GUI, that would be the absolute hammer, as my customers could see it and make use of it! Please tell me, and thank you very much in advance!!

And I also dont know whats better, as http webproxy or websocket, for real time usage for customers. I just started this adventure, as a customer asked me for the OutlineKB system (from getoutline.com, community version). Till then i was only working with the standard DB/PHP Systems as Joomla and WP, never in the new NodeJS area with static files, or headless CMS as Strapi or Ghost. I just found out about them only recently a few days ago, and now trying to get more knowledge about it and NodeJS. So I really appreciate your help in this matter, as I think here is a new field for the future to work on. Thank you very much!
 
Ah you mean GUI for customers. No there is none.
I would advice to install also the wsgi modules via litespeed. You can do this:
/usr/local/lsws/admin/misc/enable_ruby_python_selector.sh

In case someone wants to use python :)

Or download and install:

For node.js it is simple, you install node.js the way you would like to.
So if you would do it via dnf, then I would recommend to check the module and choose nodejs version

So like this:
Code:
dnf module list nodejs
Then enable the version you want for example if you want nodejs 20.
Code:
dnf module enable nodejs:20
Then install
Code:
dnf install nodejs
Remember this means server wide Node.js.

If you want to have user based node.js I would recommend using NVM (Node Version Manager) this would mean you will need to login via ssh as the user.

NVM is here: https://github.com/nvm-sh/nvm?tab=readme-ov-file#installing-and-updating

For example if you have a user called kiwi:
Code:
su - kiwi

wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

source ~/.bashrc

check if it works:

command -v nvm

But this your choice.

Tip: What I use on my server is this:

Anyway, back to node.js
When you have a node.js app running you can just proxy it via LiteSpeed.

As of v6.0, LiteSpeed Web Server supports ProxyPass natively. It is no longer required to set up an external app.
ProxyAddHeaders is also supported. So you can also make custom httpd config for users and add the proxypass in the vhost file.

Or just use the [P] option in .htaccess
So if you have a node.js app running with a server on port 5000 you can just do this in the htaccess of the domain:

Code:
RewriteEngine On
RewriteRule ^(.*)$ https://127.0.0.1:5000/$1 [P,L]

If you want to proxy to a domain name you shoudl use the proxypass in the vhost or make an app in Litespeed webadmin.

If you need help you always PM me for more info. But Litespeed has good documentation how to set it up.
 
There is UNIT software in DirectAdmin, that makes it possible. Instructions on how to install it can be found by the link:

- https://docs.directadmin.com/webservices/nginx_unit/

The UNIT interface in DirectAdmin allows to create applications based on NodeJs, Python, Ruby, Java, Perl (it is not about software development though). It is about managing them in Web-UI of DirectAdmin. And then it allows to configure a webserver to route requests to the applications.

Thus, if a user has a Node-JS application, they would need:

1. upload an application to /home/USER/domains/DOMAIN/appdir
2. install dependences and requirements using npm
3. add the application in DirectAdmin UNIT using CREATE function
4. add a route for a domain
5. wait for a changes to apply

This is the simple set of steps can be seen on the same link posted above.

I tested it on CentOS 7, AlmaLinux 8 and 9 with apache+nginx, litespeed, openlitespeed and apache.

Found issues:


1. CentOS7, AlmaLinux 9: failed dependences and conflicts with Java, Python, whenever multiple versions of libraries are installed.
2. LiteSpeed: routing fails to identify a valid host when requests proxied to http://127.0.0.1:8090/ (work fine with an external IP).
3. "Unit" should be allowed for users in their preferences and hosting packages. Disable/enable it for changes to take an effect.
4. Other minor issues with installation of Unit


Should you have issues with Unit in DirectAdmin interface, one might need to run:

Code:
/usr/local/directadmin/custombuild/build rewrite_confs

In certain cases the UNIT is missing "listeners" after an installation:

Bash:
# /usr/bin/curl -s -X GET --unix-socket /var/run/unit/control.sock http://localhost/config/
{
        "listeners": {},
        "routes": [],
        "applications": {}
}

They should be shown in the reply, for example:

Bash:
[root@dev ~]# /usr/bin/curl -s -X GET --unix-socket /var/run/unit/control.sock http://localhost/config/
{
        "listeners": {
                "*:8090": {
                        "pass": "routes/$host"
                },

                "*:8091": {
                        "pass": "routes/$host",
                        "tls": {
                                "certificate": "hostname"
                        }
                }
        },

        "routes": {},
        "applications": {}
}
[root@dev ~]#

The listener "*:8091" is missing by default, and it is fine.

Please can anybody enlighten me, how NodeJS is proposed to work under Litespeed in DA?

OK, this is all for now, that I have.
 
Ah you mean GUI for customers. No there is none.
I would advice to install also the wsgi modules via litespeed. You can do this:
/usr/local/lsws/admin/misc/enable_ruby_python_selector.sh

In case someone wants to use python :)

Or download and install:

For node.js it is simple, you install node.js the way you would like to.
So if you would do it via dnf, then I would recommend to check the module and choose nodejs version

So like this:
Code:
dnf module list nodejs
Then enable the version you want for example if you want nodejs 20.
Code:
dnf module enable nodejs:20
Then install
Code:
dnf install nodejs
Remember this means server wide Node.js.

If you want to have user based node.js I would recommend using NVM (Node Version Manager) this would mean you will need to login via ssh as the user.

NVM is here: https://github.com/nvm-sh/nvm?tab=readme-ov-file#installing-and-updating

For example if you have a user called kiwi:
Code:
su - kiwi

wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

source ~/.bashrc

check if it works:

command -v nvm

But this your choice.

Tip: What I use on my server is this:

Anyway, back to node.js
When you have a node.js app running you can just proxy it via LiteSpeed.

As of v6.0, LiteSpeed Web Server supports ProxyPass natively. It is no longer required to set up an external app.
ProxyAddHeaders is also supported. So you can also make custom httpd config for users and add the proxypass in the vhost file.

Or just use the [P] option in .htaccess
So if you have a node.js app running with a server on port 5000 you can just do this in the htaccess of the domain:

Code:
RewriteEngine On
RewriteRule ^(.*)$ https://127.0.0.1:5000/$1 [P,L]

If you want to proxy to a domain name you shoudl use the proxypass in the vhost or make an app in Litespeed webadmin.

If you need help you always PM me for more info. But Litespeed has good documentation how to set it up.

I`m sorry for my late answer, i was out of office.

Wow, Stije, thank you very much for this great tutorial, and how you explain me all the steps! I highly appreciate it, will go and learn and try it!
Also thank you for the PM offer! Maybe I´ll need it :)
 
There is UNIT software in DirectAdmin, that makes it possible. Instructions on how to install it can be found by the link:

- https://docs.directadmin.com/webservices/nginx_unit/

The UNIT interface in DirectAdmin allows to create applications based on NodeJs, Python, Ruby, Java, Perl (it is not about software development though). It is about managing them in Web-UI of DirectAdmin. And then it allows to configure a webserver to route requests to the applications.

Thus, if a user has a Node-JS application, they would need:

1. upload an application to /home/USER/domains/DOMAIN/appdir
2. install dependences and requirements using npm
3. add the application in DirectAdmin UNIT using CREATE function
4. add a route for a domain
5. wait for a changes to apply

This is the simple set of steps can be seen on the same link posted above.

I tested it on CentOS 7, AlmaLinux 8 and 9 with apache+nginx, litespeed, openlitespeed and apache.

Found issues:


1. CentOS7, AlmaLinux 9: failed dependences and conflicts with Java, Python, whenever multiple versions of libraries are installed.
2. LiteSpeed: routing fails to identify a valid host when requests proxied to http://127.0.0.1:8090/ (work fine with an external IP).
3. "Unit" should be allowed for users in their preferences and hosting packages. Disable/enable it for changes to take an effect.
4. Other minor issues with installation of Unit


Should you have issues with Unit in DirectAdmin interface, one might need to run:

Code:
/usr/local/directadmin/custombuild/build rewrite_confs

In certain cases the UNIT is missing "listeners" after an installation:

Bash:
# /usr/bin/curl -s -X GET --unix-socket /var/run/unit/control.sock http://localhost/config/
{
        "listeners": {},
        "routes": [],
        "applications": {}
}

They should be shown in the reply, for example:

Bash:
[root@dev ~]# /usr/bin/curl -s -X GET --unix-socket /var/run/unit/control.sock http://localhost/config/
{
        "listeners": {
                "*:8090": {
                        "pass": "routes/$host"
                },

                "*:8091": {
                        "pass": "routes/$host",
                        "tls": {
                                "certificate": "hostname"
                        }
                }
        },

        "routes": {},
        "applications": {}
}
[root@dev ~]#

The listener "*:8091" is missing by default, and it is fine.



OK, this is all for now, that I have.

Also a big thank you to you, Alex! The implementation in DA was never clear to me, now I see where its going. Its serverwide install, if i understand correctly.
Please, could you explain this 2 steps a little bit more?
>"3. add the application in DirectAdmin UNIT using CREATE function" - where and how?
> "4. add a route for a domain" - do you mean in DNS, or what route?
Thank you!
 
LiteSpeed: routing fails to identify a valid host when requests proxied to http://127.0.0.1:8090/ (work fine with an external IP).

It depends on how the nodejs app has been configured. And then tell to litespeed how to proxy to "localhost/127.0.0.1/domain.tld/etc."
For example if the node uses a hostname you need to proxy different.



I never tested with litespeed and the nginx unit. Never seemed to need it if you have litespeed enterprise running
 
And then tell to litespeed how to proxy to "localhost/127.0.0.1/domain.tld/etc."
For example if the node uses a hostname you need to proxy different.

All the ModRewrite lines are added to LiteSpeed by DirectAdmin, when I create routes in nginx UNIT. I can not choose an IP, and I can not change the lines. They are hardcoded into DA binary.

The issue for now is that, I don't have another server with PRO pack and LiteSpeed, in order to see whether the issue persists on a new setup or not. Probably I will install a new server for testing it later.
 
Ah yes when you create it via NGINX Unit. I never used it. Maybe you can control the routes via the unit api? Or edit them?

NGINX and litespeed is not really a happy couple like it with apache. So i never use nginx stuff with LiteSpeed. I could test this maybe. Interesting to see how it will handle :)
 
Ah yes when you create it via NGINX Unit. I never used it. Maybe you can control the routes via the unit api? Or edit them?

It is not about controlling routes. They are actually under my control in DirectAdmin webinterface on the UNT page at a user level. It is about ModRewrite rules.

I've got a setup LiteSpeed+Nginx UNIT on AlmaLinux release 8.9 + DirectAdmin with PRO and UNIT support.

I created Node.JS and Ruby applications in Nginx UNIT:

2024-05-20_145717_poralix.png


then added routes:

2024-05-20_145958_poralix.png


Background: In order to proxy requests from the world to the nginx UNIT applications DirectAdmin adds the following line:

Code:
RewriteRule ^/myapp/?(.*)$ http://127.0.0.1:8090/myapp/$1 [P,E=Proxy-Host:example.poralix.net]

In my case I have:

Code:
RewriteRule ^/hello/?(.*)$ http://127.0.0.1:8090/hello/$1 [P,E=Proxy-Host:example.poralix.net]
    RewriteRule ^/myapp/?(.*)$ http://127.0.0.1:8090/myapp/$1 [P,E=Proxy-Host:example.poralix.net]
    RewriteRule ^/rubyapp/?(.*)$ http://127.0.0.1:8090/rubyapp/$1 [P,E=Proxy-Host:example.poralix.net]


The URLs result in HTTP/404 error in a browser, whenever I hit http://example.poralix.net/hello/ http://example.poralix.net/myapp/ or http://example.poralix.net/rubyapp/

if I change the lines to:

Code:
RewriteRule ^/hello/?(.*)$ http://1.2.3.4:8090/hello/$1 [P,E=Proxy-Host:example.poralix.net]
    RewriteRule ^/myapp/?(.*)$ http://1.2.3.4:8090/myapp/$1 [P,E=Proxy-Host:example.poralix.net]
    RewriteRule ^/rubyapp/?(.*)$ http://1.2.3.4:8090/rubyapp/$1 [P,E=Proxy-Host:example.poralix.net]

Where 1.2.3.4 is a public IP for the mentioned domain, then all the three URLs work fine and I see content from my applications.

If I test the URLs in CLI using cURL, then I got HTTP/200 OK in all cases:

- Public IP:

Bash:
# curl -i --header "Host:example.poralix.net" http://1.2.3.4:8090/myapp/
HTTP/1.1 200 OK
Content-Type: text/plain
Server: Unit/1.32.1
Date: Mon, 20 May 2024 07:54:17 GMT
Transfer-Encoding: chunked

Hello, World! From native...

- Internal IP:

Bash:
# curl -i --header "Host:example.poralix.net" http://127.0.0.1:8090/myapp/
HTTP/1.1 200 OK
Content-Type: text/plain
Server: Unit/1.32.1
Date: Mon, 20 May 2024 07:54:29 GMT
Transfer-Encoding: chunked

Hello, World! From native...

The Proxy-Host header in the ModRewrite rules works the same as Host header in cURL. For some reasons the header does not work as desired when requests are proxied to 127.0.0.1 and I see only $_SERVER['HTTP_X_FORWARDED_HOST'] even if I add my own rules:

Code:
RewriteRule ^/test1/?(.*)$ http://127.0.0.1:80/$1 [P,E=Proxy-Host:example.poralix.net]
RewriteRule ^/test2/?(.*)$ http://1.2.3.4:80/$1 [P,E=Proxy-Host:example.poralix.net]

And the issue exists only when I try LiteSpeed, all other webservers: openlitespeed, nginx, apache - do not have the issue.

Probably @fln can check it on their side too.
 
Last edited:
Updated DirectAdmin to v.1.663 e3952a646cfd0f8aeacda4a1e54e2c66a61a22a4

It is fixed there. Another way to proxy requests is used there for LiteSpeed:


Code:
        <Location "/rubyapp">
                ProxyPreserveHost On
                RequestHeader set Host "devXXXX.poralix.net"
                ProxyPass "http://127.0.0.1:8090/rubyapp"
                ProxyPassReverse "http://127.0.0.1:8090/rubyapp"
        </Location>

Nice https://docs.directadmin.com/change...eed-unit-use-proxypass-instead-of-rewriterule

It was found that the RewriteRule in LiteSpeed was not passing the Host header, thus Unit was not able to pass the request to the correct route. Testing of various LiteSpeed versions confirmed that the ProxyPass is required to properly have LiteSpeed pass the Host header to Unit.
 
Back
Top