Web servers
The request path
Section titled “The request path”browser → Caddy on :443 TLS terminates here, using your local CA's certificate → shared nginx on :18088 one server block per site, matched by hostname → php-fpm pool one per PHP version, not one per site → your codeCaddy is the edge and never talks to PHP directly. nginx serves every site by default, which is why the tenth site costs about as much memory as the first.
Per-site overrides
Section titled “Per-site overrides”A site can opt out of the shared nginx:
rex site server myshop.rex apache| Server | Version | On | Use it when |
|---|---|---|---|
| nginx | 1.30.4 | macOS, Windows, Linux | Default. Shared, fastest, lowest overhead |
| Apache | 2.4.68 | macOS only | The project relies on .htaccess |
| FrankenPHP | 1.12.4 | macOS and Linux | You want its worker mode or Caddy-style config |
| OpenLiteSpeed | 1.9.3 | macOS and Linux | You deploy to a LiteSpeed host and use LSCache |
On an operating system without it, an override is refused with a message naming the OS — never offered and then broken. The refusal comes before anything is downloaded: until this release, switching a Windows site to OpenLiteSpeed (or a Linux one to Apache) first tried the download and failed with a download error, instead of the sentence that says why.
An override runs a per-site process on a loopback-only port — 8200–8299 for FrankenPHP, 8300–8399 for Apache, 8400–8499 for OpenLiteSpeed — and the edge routes that hostname to it. The override is never the edge and never binds 443.
Apache and .htaccess
Section titled “Apache and .htaccess”The Apache override ships with AllowOverride All, so .htaccess files work as they do in
production.
FrankenPHP brings its own PHP
Section titled “FrankenPHP brings its own PHP”The pinned FrankenPHP binary embeds PHP 8.5.8. A site on the FrankenPHP override is served by that runtime — not by the shared php-fpm pools, and not by whatever the site’s PHP version setting says.
So on a FrankenPHP site the PHP version picker is read-only, annotated with what actually serves. It used to be editable, which meant it could show 8.2 on a site being served by 8.5.
OpenLiteSpeed
Section titled “OpenLiteSpeed”rex site server myshop.rex openlitespeedThe reason to pick it is a LiteSpeed host: the LSCache module ships switched on, so the
LiteSpeed Cache plugin works as it does in production, and .htaccess is read. No macOS binary
of OpenLiteSpeed existed to ship, so this one is rexenv’s own build, 1.9.3, from pinned
sources with a small patch set — the same recipe on macOS and Linux.
Like Apache, it has no PHP of its own: .php goes over FastCGI to the site’s shared
php-fpm pool, so the site is served by the PHP version it says it runs. Each site gets its own
server root under rexenv’s data folder, with its config, run directory and LSCache storage.
The admin console is off, and so is OpenLiteSpeed’s release check.
A site with a root .htaccess routes itself, as on any LiteSpeed host; without one, rexenv’s
own rules route it. Dotfiles answer 404 either way.
One refusal is specific to it. Per-site environment variables reach PHP through rewrite
rules, which can quote a value with ' or " but not both — so a value containing both quote
characters is refused when you save it for an OpenLiteSpeed site, or switch a site that has one
to OpenLiteSpeed:
env var ‘NAME’: OpenLiteSpeed cannot pass a value that contains both ’ and “ (its rewrite flags have no escape for the quote) — drop one of them, or use another web server for this site