CloudLinux¶
The LiteSpeed development team works very closely with the CloudLinux team to make sure the capabilities shared between LiteSpeed and CloudLinux work seamlessly.
CloudLinux and LiteSpeed Containers are separate and distict ways to limit resource usage and present a sandboxed environment. Learn more about LiteSpeed Containers.
Important Points¶
-
The LiteSpeed Web Server Installer must be run the same way on a CloudLinux system as you would on cPanel without CloudLinux.
-
To use the CloudLinux PHP Selector only, instead of cPanel's EA4 Multi-PHP Manager, please see PHP Selector.
-
For more detailed configuration on LVE, CageFS or PHP Selector, please see CloudLinux documentation.
Enable CageFS¶
Note
This step is only required if you have installed CageFS after installing LiteSpeed.
To enable in LSWS, go to Configuration > Server > General > CloudLinux and set CloudLinux to CageFS
or CageFS without suEXEC
.
Note
A LSWS mount point will be included in the skeleton automatically if LSWS is installed **prior to** CageFS.
If LSWS gets installed after CageFS, run following command to get LSWS added to the skeleton:
/usr/sbin/cagefsctl --create-mp
/usr/sbin/cagefsctl --remount-all
/usr/sbin/cagefsctl --update
Note
If the update mentions needing to force update, force the update.
Ruby/Python/Node.js Selector¶
Ruby/Python/Node.js Selectors are supported by LiteSpeed Web Server out of the box. You will need to follow the instructions in the CloudLinux selector to make your application work with Apache first before switching to LSWS. You can refer to the official CloudLinux documentation.
LiteSpeed supports the Apache mod_passenger
configuration generated through CloudLinux selectors. However, behind the scenes, LiteSpeed's is a completely different implementation.
Note
CloudLinux should have installed all required packages automatically. For an older installation, you may need to run the script to install the required ruby/python lsapi modules:
/usr/local/lsws/admin/misc/enable_ruby_python_selector.sh
Supported mod_passenger directives¶
LiteSpeed supports the following Apache mod_passenger configuration directives:
PassengerBaseURI
PassengerAppRoot
PassengerAppEnv
PassengerAppType
PassengerStartupFile
PassengerPython
PassengerRuby
PassengerNodejs
PassengerUser
PassengerGroup
About Node.js Support¶
There is virtually no downside to using Node.js with LSWS. All of your existing Node.js packages which can include Ghost or any homegrown software, will run with virtually no changes through the LiteSpeed port. LiteSpeed continues to serve all of your non-Node.js traffic and it will now additionally service the Node.js traffic.
How LiteSpeed Works with NodeJS Selector¶
For a Node.js application managed by CloudLinux Node.js selector, LSWS does an automatic ws://
proxy to the Node.js backend, if the request does a WebSocket upgrade. No extra configuration is required.
When direct connecting to a Node.js server, test with
ws://...
When going through a LSWS HTTPS proxy server, use
wss://...
When a Node.js server is started through LSWS NodeJS selector integration (mod_passenger
), the TCP socket is replaced with an auto-generated Unix domain socket, so direct access the TCP port may fail.
How to Test Node.js with LSWS¶
You can create a file with the name index.js
. Place the following content in the file:
var http = require('http');
var server = http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
var message = 'It works!\n',
version = 'NodeJS ' + process.versions.node + '\n',
response = [message, version].join('\n');
res.end(response);
});
server.listen();
Point your browser to http://example.com/index.js
.
The result:
It works!
NodeJS 10.11.0
Note
Any port specifications in the listen
function are ignored. The server is processed by the Node.js function of LiteSpeed automatically.
Avoid app frequently stopping and starting¶
See the LSAPI_AVOID_FORK documentation to avoid frequently stopping and starting child processes. This might be preferred in a dedicated hosting environment because it may be faster to recycle existing processes, even if it means sometimes running unused processes.
Increase Python App Max Children Limit¶
Navigate to cPanel > Set up Python App and select Edit for the app that needs the limit adjusted. Navigate to Environment variables > Add variable. Create a new variable with the name LSAPI_CHILDREN
and set the value as you see fit.
The default value is 6
, but 10
or 15
might be more appropriate for your traffic level.
Click Save in the upper right corner, and restart the application in order to reload the variables.
You can use the following script to verify that the max children process limit has been increased accordingly:
import os
import sys
sys.path.insert(0, os.path.dirname(__file__))
def application(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/html; charset=utf-8')])
body = ''
for i in os.environ:
body += f'{i}: {os.environ[i]}<br>'
return [body.encode()]
To apply a new max children process limit globally, open the LiteSpeed WebAdmin Console, navigate to Server conf > App server > Python WSGI Default Settings > Environment , and add LSAPI_CHILDREN=XX
. (Replace XX
with the value you wish to apply, for example, 10
.)
Restart LiteSpeed Web Server to apply the new value.
Steps to Test Python and Ruby Selector¶
- Make sure Python and Ruby Selector works properly under Apache (follow CloudLinux instructions to install and configure).
- Test a Ruby or Python application with Apache and ensure it is running OK.
- Switch to LiteSpeed and try a ruby/python app
Python error log output¶
The Run on Startup option controls where you will find the stderr.log
file.
In your WebAdmin Console, navigate to Configuration > Server > App Server and scroll down to the Python WSGI Default Settings section.
If Run on Startup is set to Yes (Detached Mode)
, which is the default setting, then errors will be logged to the server log (for example /var/log/apache2/stder.log
).
If Run on Startup is set to any other setting, then errors will be logged at the application root (for example /home/user/app/stderr.log
).
Restart Application¶
The application can be restarted by touching the <app_root_dir>/tmp/restart.txt
file. For example, if a python application is located at /home/user1/mypythonapp
the command would be:
touch /home/user1/mypythonapp/tmp/restart.txt
This will tell the server to restart the application.
Node.js Selection with NextJS Server¶
If you want to run a NextJS application with Node.js, you first must compile the NextJS project as a standalone. This will create a server.js
script that you can use as a startup script.
The provided server.js
script bypasses the CLI and works without stdin.resume()
.
Note
This is not the "custom server" method, and all of the NextJS functionalities are available.
Node.js Automatic WebSocket Proxy¶
For a Node.js application managed by CloudLinux Node.js selector, LSWS does an automatic ws://
proxy to the Node.js backend, if the request does a WebSocket upgrade. No extra configuration required.
When direct connecting to a Node.js server, test with
ws://...
When going through a LSWS HTTPS proxy server, use
wss://...
When a Node.js server is started through LSWS Node.js selector integration (mod_passenger), the TCP socket is replaced with an auto-generated Unix domain socket, hence direct access the TCP port may fail.
Log file locations¶
-
Python/NodeJS STDERR log The application will log STDERR to
stderr.log
under the application root directory. -
Ruby/Rack application STDERR log The application will log STDERR to
log/stderr.log
under the application root directory. -
Node.js console log For console log, you can use
SetEnv LSNODE_CONSOLE_LOG
in.htaccess
. For example, the following allows you to haveconsole.log
under the application root directory:
SetEnv LSNODE_CONSOLE_LOG console.log
CRIU¶
Stop
Due to stability issues, LiteSpeed CRIU support has been completely disabled.
Troubleshooting¶
508 Resource Limit Reached¶
At WebAdmin Console > Server General > Server Process > CloudLinux, there is a CloudLinux configuration option to specify whether to enable CloudLinux's Lightweight Virtual Environment (LVE) when it exists. You can use LiteSpeed with LVE to achieve better resource management.
Once it is enabled, sometime you may experience 508 Resource Limit Reached
error. Actually it is not a LiteSpeed error, but a message from CloudLinux to show that you may reach the concurrent connections limit. Increasing the LVE limit may fix the issue.
Please see CloudLinux documentation for more details.
Site Capacity Limit Reached¶
In a shared hosting environment with CloudLinux installed, PHP for one account fails and reports the error page Site reached its capacity limit!
You may experience the following error in the stderr.log
[STDERR] Unable to create lock file: Permission denied
[STDERR] Wed May 27 17:28:51 2015 (19046): Fatal Error Unable to create lock file: Bad file descriptor (9)
If the debugging logging is activated, you may see the following:
No Request has been processed successfully through this connection, the maximum connections allowed will be reduced!
HttpExtConnector::tryRecover()...
Max retries has been reached, 503!
Disabling opcode cache doesn't help.
PHP could not be started successfully for that user. You should run the PHP binary as that user account and find out why.
sudo -u <user_name> /path/to/lsphp5/binary -i
Fixing any error in the output may fix the overall problem. However there is no error for it.
Unable to create lock file: Permission denied
could be a Zend Opcache problem, however the same problem occurred with PHP 5.3 and 5.4 using APC. Therefore disabling Zend Opcache in PHP 5.5 and 5.6 didn't help.
Try to find correlated log entries in error.log
and stderr.log
by matching the timestamps. For example, you got the following in your error log:
2015-05-27 17:28:49.760 [INFO] Remove pid: 18989, exitcode: 254
which means that a PHP process exited with code 254. Locate the related error in stderr.log:
2015-05-27 17:28:51.069 [STDERR] Unable to create lock file: Permission denied
2015-05-27 17:28:51.070 [STDERR] Wed May 27 17:28:51 2015 (19046): Fatal Error Unable to create lock file: Bad file descriptor (9)
Check if the CloudLinux CageFS was setup correctly since other users do not have the same error.
After remounting CageFS, the website works fine.
The first trouble-shooting step when CageFS is used, is to force update the cage, and turn off/on CafeFS for that user.
PHP suEXEC Max Conn is too High¶
LiteSpeed Web Server's PHP suEXEC Max Conn setting should always be set to a value less than the CloudLinux LVE EP limit.
LVE is a kernel-level technology developed by the CloudLinux team.
Each LVE limits the amount of entry processes (web server processes entering into the LVE) to prevent a single site exhausting all web server processes. If the limit is reached, then mod_hostinglimits
will not be able to place web server processes into the LVE and will return a 508 error. This results in very heavy sites slowing down and returning 508 errors without impacting other users.
If the site is limited by CPU or IO, then the site will start responding slower. If the site has limits set on memory or its number of processes, then the user will receive 500 or 503 errors that the server cannot execute the script.
PHP suEXEC Max Conn is a LiteSpeed Web Server setting which specifies the maximum number of concurrent PHP processes that can be created by LSWS for each user when running PHP scripts in suEXEC mode. The default value for this setting is 5. This limit is per user per lshttpd process. Thus, if you have a Web Host Professional license, this limit will be doubled. The limit will be 4x for a Web Host Enterprise license, and so on.
Limits on entry processes(EP) control the number of entries into an LVE. NPROC controls the total number of processes within an LVE. Once the limit is reached, no new processes can be created (until another one dies). When that happens, the NPROC counter is incremented. In these cases, LSWS might return 500 or 503 errors.
For shared hosting environments, PHP suEXEC Max Conn
should not be set too high. Generally 5 or 10 is acceptable. Under normal circumstances, this value should not exceed 50. If the PHP suEXEC Max Conn
limit is reached, another php connection will be created. PHP suEXEC Max Conn
should always be set to a value that is less than the CloudLinux user account EP limit. A high PHP suEXEC Max Conn
value doesn't necessarily result in a performance gain. A lot of the time, setting this too high may over kill the server. Good practice is to start it at 5 or 10 and monitor the real time stats for your busiest domain during the peak traffic time. If the waitQ is constantly > 0, PHP suEXEC Max Conn
should be gradually increased but it must always be less than the EP limit for all LVE accounts. PHP suEXEC Max Conn
is a global setting which will impact all shared hosting accounts.
For non-shared hosting environments, PHP suEXEC Max Conn
can be adjusted to values a little higher such as 50 or even 500 but generally not over 1000.
The easiest way to determine what the SuExec Max Conn limit should be is to use the following equation:
SuExec_MaxConn = CloudLinux EP / Number of CPU License
For example, if you have an EP limit of 20 and a Web Host Professional license:
SuExec_MaxConn = 20 / 2
The result of this equation is the maximum number that the SuExec Max Conn field should be; in this case SuExec Max Conn should be set to 10. If the CloudLinux EP or Number of CPU License is an odd number ( other than 1 ), be sure to round the SuExec Max Conn result down as rounding up may go over the maximum CloudLinux EP limit and create additional issues.
Node.js Code is Visible¶
When viewing the application, you may only see the code of the file like this:
Navigate to cPanel > NodeJS selector and check if your application is started. You can start it from there or restart it. If you still see only the source code make sure that your server is running LiteSpeed Web Server version 5.3 or higher.
You can also verify that the 'Litespeed NodeJS Service' is running. From a command prompt enter:
ps -ef|grep node
One of the displayed running processes should be shown like this
lsnode:/home/USER/public_html/APPDIR/
When troubleshooting, you may want to bring up a stand-alone Node.js server and verify that the software works through that, to be sure that the problem is not in the Javascript itself.
Application does not work¶
If your application does not work properly, you can try two simple steps to check if the application has been set up properly:
- If possible, switch back to Apache temporarily to verify if the application works properly under Apache.
- Check if any error has been logged into
<APP_ROOT_DIR>/stderr.log
. If it has, fix the error and try again.
For example:
A Python application writes an error to stderr.log under the application root directory, /home/user1/dingodossier/mbntp/stderr.log
:
Traceback (most recent call last):
File "/home/user1/dingodossier/mbntp/passenger_wsgi.py", line 8, in <module>
wsgi = imp.load_source('wsgi', 'mbntp/wsgi.py')
File "/home/user1/virtualenv/dingodossier_mbntp/3.4/lib64/python3.4/imp.py", line 171, in load_source
module = methods.load()
File "<frozen importlib._bootstrap>", line 1220, in load
File "<frozen importlib._bootstrap>", line 1200, in _load_unlocked
File "<frozen importlib._bootstrap>", line 1129, in _exec
File "<frozen importlib._bootstrap>", line 1471, in exec_module
File "<frozen importlib._bootstrap>", line 321, in _call_with_frames_removed
File "mbntp/wsgi.py", line 10, in <module>
from django.core.wsgi import get_wsgi_application
ImportError: No module named 'django'
This indicates Django was not properly set up for the application.
Ruby: Disabling X-Sendfile¶
By default LiteSpeed supports X-Sendfile
internal redirects for Ruby on Rails, but for shared hosting environments, that can trigger problems. For example, the user will not have permissions to access the Redmine directory.
Go to your Redmine folder and put the following in the .htaccess
file:
SetEnv RACK_NO_XSENDFILE 1
Note
This is an example for Redmine but you can use the same solution in any Ruby on Rails application.
Node.js: Ignored Environment Variables¶
Normally, entering the environment variables in the Node.js selector should be enough but if you find they are not taking effect then you can manually do it.
Go to your Node.js folder and put the following in the .htaccess
file (or add to the existing entry if applicable):
SetEnv SAMPLE_ENV_VAR ...
Unexplained site downtime¶
If you have sites experiencing unexplained downtime, and you are using Imunify360, we recommend disabling it. If the downtime ceases, then this is likely not a LiteSpeed or cPanel issue. Please contact CloudLinux support.