Stack differences
LEMP, LAMP, OLS, MERN and Docker — what each stack serves, which screens it hides, and everything that changes on OpenLiteSpeed.
The stack is chosen once, by the installer's --stack= flag, and recorded on
the server. Almost every "why is that screen not there" question answers to it.
curl -fsSL https://raw.githubusercontent.com/DipaliRadadiya/open-source-sa/main/install.sh \
| sudo bash -s -- --stack=lempA stack is two decisions: which web server gets installed, and what kind of application this box will serve. The second one is the one the rest of the panel reads.
The five presets
| Stack | Web server | Serves | Panel-managed databases |
|---|---|---|---|
lemp | nginx | PHP, static | Yes |
lamp | Apache | PHP, static | Yes |
ols | OpenLiteSpeed | PHP, static | Yes |
mern | nginx | Node.js, static | Yes |
docker | nginx | Containers only | No |
mern maps to nginx because MERN uses nginx — it is not a web server of its
own; nginx sits in front of your Node processes.
The stack cannot be changed from the panel
There is no screen that turns a PHP server into a container server. The decision is made by the installer and lives in the server's capability record. Moving a box between stacks means reinstalling it.
What "serves PHP" actually means
Every stack has PHP installed, including the Docker one — the panel is itself a PHP application, so it could hardly not. That is a different question from whether the box will host PHP sites, and the panel keeps the two apart.
So on a Docker server the PHP runtime is present and working, and the create catalog still offers you no PHP site types. That is deliberate, not a bug.
Which screens your stack shows
The sidebar is built from the stack, so two servers running the same version of OSS Panel can legitimately show different menus.

- Databases appears wherever the box runs applications on the host — every stack except Docker. A container server says no: an application that needs a database brings one as a container, and the panel's own storage is SQLite regardless.
- Docker appears everywhere, but on a non-container stack it only explains itself.
- Node.js appears on every stack, including LEMP — and that is on purpose.
A LEMP box hosts no Node sites, but Node is a build tool for PHP ones: the
panel's own build-command placeholder is
npm ci && npm run build, offered on any git-deployed site. Hiding the screen wherever Node sites are not served would take it away from every Laravel site that builds its assets. - PHP follows the opposite rule: the screen is shown where the box serves PHP sites, so LEMP, LAMP and OLS have it and MERN and Docker do not — even though PHP is installed on all five.


The same rule hides application types. A site type whose serving profile this box cannot host is removed from the create catalog entirely rather than shown greyed out — see Application types for the full catalog and what each stack leaves in it.
The same catalog on two stacks
An OpenLiteSpeed server serves PHP and static, so its catalog is the PHP one — 13 types:

A MERN server serves Node and static, so the same screen offers five — and the CMS category disappears with them, because nothing is left in it:

Static site is the only type on both: it is the one profile every stack
except Docker can serve.
A server the panel did not build
A box adopted from another panel has no recorded stack. The panel treats that as unknown, not as nothing: it offers PHP, Node and static, because a migrated server is certainly already hosting something and answering "hosts nothing" would empty its catalog on a working machine.
If the guess is wrong, record the truth once:
cd /var/www/panel/backend
php artisan server:record-stack lemp # or lamp | ols | mern | dockerHow the web server is detected
Normally there is nothing to detect — the installer writes the record and the panel reads it. Detection only runs on a server nobody recorded, and it has one rule worth knowing: a running unit beats a leftover config directory.
apt remove apache2 does not delete /etc/apache2, so a box running
OpenLiteSpeed with a purged Apache can still look like an Apache server to
anything that only checks for directories. When two candidates exist, the panel
asks systemd which one is actually running.
A recorded stack is never silently overruled
If the record says Apache and the box plainly runs OpenLiteSpeed, the panel
corrects itself only when the recorded web server is not installed at all
and exactly one supported web server is running. Anything less clear-cut is
left alone and reported by
System health instead, with
the server:record-stack command that settles it. Quietly writing vhosts for
a web server nobody chose would be the worse bug.
OpenLiteSpeed: what changes
OLS is the stack that differs most, because it does not use PHP-FPM at all. It runs LSPHP — a different interpreter build, with different packages, different paths, and no per-version systemd service.
Per-site isolation works, but differently
On nginx and Apache each site gets its own PHP-FPM pool and its own socket.
On OpenLiteSpeed each site gets its own external app: its own LSAPI socket,
its own processor name, and extUser set to that site's system user.
Both arrive at the same place — one site's PHP cannot read another site's
.env — by different means.
Both stacks refuse the unsafe configuration
PHP-FPM will not start a pool with no user =, so the mistake is impossible
there. OpenLiteSpeed has no equivalent backstop: a vhost with no extUser
is perfectly valid and runs the site's PHP as the server's own account,
nobody — which every other site would also fall back to, giving the whole
box one identity. So the panel checks first and refuses to write an
OpenLiteSpeed vhost for an application that has no system user.
This is why the create form insists on a system user and offers to generate one — that account is what the vhost will run the site's PHP as:

Sites created by the panel are isolated from the start. Sites adopted from elsewhere, or created before isolation shipped, can be brought in line:
cd /var/www/panel/backend
php artisan php:isolate-allWhat the panel writes for an application called demo-ols looks like this —
its own processor, its own socket, and its own user:
extprocessor lsphp84-demo-ols {
type lsapi
address uds://tmp/lshttpd/lsphp84-demo-ols.sock
path /usr/local/lsws/lsphp84/bin/lsphp
extUser demo-ols
extGroup demo-ols
env PHP_INI_SCAN_DIR=:/home/demo-ols/demo-ols/.panel/php
}The socket is named after the application's slug, not its domain, so renaming a domain does not strip the site of its interpreter. OpenLiteSpeed confirms the switch in its own log when the worker starts:
[LocalWorker::workerExec] Config[lsphp84-demo-ols]: suExec uid 1001 gid 1001
cmd /usr/local/lsws/lsphp84/bin/lsphp, final uid 1001 gid 1001A new site answers on HTTP before it answers on HTTPS
Until you issue a certificate for it, an OpenLiteSpeed site's vhssl block
points at the panel's reject certificate (CN=unmatched.invalid), so
HTTPS returns 403 while HTTP already serves the site. That is deliberate:
an un-certificated vhost fails closed rather than answering under the panel's
own certificate. Issue SSL from the application's Domains & SSL screen and
the block is rewritten with the real certificate.
.htaccess is mostly not read
OpenLiteSpeed only re-reads .htaccess after a restart, so the panel does not
rely on it. Rewrite rules and the 8G firewall rules are rendered as directives
inside each site's vhconf.conf instead, from the same rule source the
Apache version uses.
One site type is the exception: WordPress. LiteSpeed Cache talks to the
OpenLiteSpeed cache module through .htaccess and nothing else, so for a
WordPress application the panel does treat that file as live. Changing an
application's site type changes this behaviour with it.
This is why an .htaccess you drop into a non-WordPress site on OLS appears to
do nothing: it is not being read. Put the rule in the application's settings so
the panel writes it into the vhost.
Extensions: a shorter list, and a trap
The LSPHP base install is deliberately smaller than the PHP-FPM one:
| Packages installed | |
|---|---|
| PHP-FPM | fpm, cli, common, mysql, pgsql, curl, mbstring, xml, zip, gd, intl, bcmath, soap, sqlite3, redis, igbinary, opcache |
| LSPHP | common, mysql, pgsql, curl, intl, sqlite3, redis, igbinary, opcache |
No capability is lost. mbstring, xml, zip, gd, bcmath and soap
are compiled into the LSPHP interpreter — they load on a box with none of those
packages installed.
The trap is that LiteSpeed still names them. lsphp84-gd resolves as a
package the index knows and apt refuses to install: it looks real in a search
and kills the transaction anyway. So the panel checks every extension package
with apt-cache policy before installing and skips the ones with no
installation candidate, rather than letting one bad name take down the whole
install.

Do not assume extension parity between stacks
The screenshot above is a LEMP server, where mongodb is one of the 80
extensions on offer. An OpenLiteSpeed server of the same version offers
21, and mongodb is not among them — what LSPHP can install is
whatever LiteSpeed publishes as lsphpXX-<name> for your PHP version, which
is not the set Ubuntu ships. If an application needs an extension, check the
Extensions list on the OpenLiteSpeed server itself.
Measured on an OpenLiteSpeed server running the same version: 8 of the 21 are
installed (curl, igbinary, intl, mysql, opcache, pgsql, redis,
sqlite3) and the other 13 are available to install — apcu, dbg,
imagick, imap, ldap, mailparse, memcached, msgpack, pear,
pspell, snmp, sybase and tidy.
Extensions cannot be switched off on OpenLiteSpeed
The Extensions list behaves differently here. Every installed extension reads Always on instead of carrying a toggle, and the screen says so: "On OpenLiteSpeed an installed extension is always on. You can install one here, but not switch it off." To stop using one, uninstall it.
The same screen also counts Built into PHP (47) on LSPHP against 16 on a PHP-FPM box — the compiled-in set described above, shown as a number.

Everything else about the PHP screen — installing a version, choosing the
default, editing php.ini — works the same on every stack.

Caveats
- The web server, not the stack, decides the vhost format. Two
lempandmernservers both run nginx and get the same vhost layout; what differs is what they are allowed to serve. - Changing the server's default PHP version does not move your applications — each one keeps its own. That is true on every stack.
- Docker and MERN servers still have PHP installed, but they hide the PHP screen. The tab is gated on whether the box serves PHP sites, not on whether PHP exists — so it is present on LEMP, LAMP and OLS, and absent on MERN and Docker even though the panel itself is running on PHP there.
- OpenLiteSpeed supports the 8G web firewall, same rule set as Apache; see Web firewall.
Reference & troubleshooting
How the five stacks differ, how to put your own brand on the panel, where the translations live, and what to do when something goes wrong.
Branding & white-labelling
Put your own name, logos, favicon and accent colour on the panel with seven environment variables — and name every file on the server with your own slug.