# Frequently asked questions

URL: https://scalws.com/docs/guide/faq/
Source: `docs/guide/faq.md` in the ScalWS repository

## General

### What is ScalWS?

Scale Web Server (ScalWS) is a multi-tenant web and application server for Linux, written in
Rust. One process serves static files, reverse-proxies to upstreams, and runs PHP-FPM,
Node.js, Python (ASGI and WSGI) and container applications as managed, supervised runtimes.

You organise sites as tenant → application → domains. Each tenant can get cgroup v2 limits
for CPU, memory, pids and disk I/O. Other features:

* a response cache in memory and on disk
* ACME certificates
* deterministic security rules and a deterministic worker optimizer
* correlated diagnostics
* an admin API, used by `scalwsctl`
* an optional local AI advisor that only explains and never acts

The programs:

| Program | Role |
|---|---|
| `scalwsd` | The server. |
| `scalws-controller` | Runs several `scalwsd` instances on shared listening sockets: the Adaptive Runtime. |
| `scalwsctl` | The operator CLI. |
| `scalws-console` | The web administration. |

See [../ARCHITECTURE.md](https://scalws.com/docs/architecture/) and [cli.md](https://scalws.com/docs/guide/cli/).

### Which operating systems does it run on?

Linux on x86_64. The packages support:

* AlmaLinux, Rocky Linux and Oracle Linux 8, 9 and 10 (for 10 see the
  [EL10 note](https://scalws.com/docs/guide/installation/#el10)), and Fedora 44: `.rpm` from the signed dnf repository;
* openSUSE Leap 16.0 and 15.6, SLES 16.0 and 15 SP7: the same `.rpm` and repository, with
  zypper;
* Debian 12 and 13, Ubuntu 22.04, 24.04 and 26.04: `.deb` from the signed apt repository;
* Alpine Linux 3.24: `.apk` from the signed apk repository, with OpenRC services
  ([Alpine Linux](https://scalws.com/docs/guide/installation/#alpine-linux)).

One build serves all of them except Alpine (glibc 2.28 or later); Alpine gets a static
musl build of the same source. On the RHEL family and SUSE 16 ScalWS runs with SELinux
enforcing under its own policy module. On SUSE 15 (AppArmor or no security module) no
SELinux module is loaded and there is no AppArmor profile: ScalWS runs unconfined, as on
Debian and Ubuntu. On Alpine there are no systemd units: the services run with the same
user and capability limits and with `--service-sandbox` (a Landlock write fence and a system
call deny-list), without a private `/tmp`, private devices or namespaces, and `scalwsctl
status` says so ([Alpine Linux](https://scalws.com/docs/guide/installation/#alpine-linux)). No control panel supports
SUSE or Alpine. On EL8, tenant limits need a switch to cgroup v2. See [installation.md](https://scalws.com/docs/guide/installation/#supported-systems); for servers
with a control panel, see the [panel and system matrix](https://scalws.com/docs/guide/control-panels/#panels-and-systems).

The code builds on other systems for development, but Linux-only features such as
cgroups, signal-based reload, Unix-socket upstreams and the controller are not available
there.

### Should I run `scalws-controller` or `scalwsd.service`?

The package provides both units. They exclude each other: enable one.

* **`scalws-controller`** (the default) supervises several `scalwsd` instances and can
  scale them. ScalWS Console manages the server through it. Under the controller,
  applications must be external endpoints: PHP through an existing PHP-FPM pool
  (`php: {fastcgi: ...}`), and everything else through `proxy`.
* **`scalwsd.service`** runs one process. Use it when you want ScalWS to start and
  supervise PHP-FPM pools, Node.js or Python processes, or containers itself (managed
  runtimes).

See [../adaptive-runtime.md](https://scalws.com/docs/adaptive-runtime/) and
[troubleshooting.md](https://scalws.com/docs/guide/troubleshooting/#scalws-controller).

### How does it compare with nginx and Apache?

It covers similar ground with a different design:

* **Configuration** is one validated YAML file, optionally with one short file per site.
  It is checked completely before every reload and swapped atomically. A bad reload never
  replaces the running configuration.
* **Application runtimes** (PHP-FPM, Node.js, Python) are started and supervised by the
  server, with readiness checks, crash backoff and draining. With nginx you would add
  separate process managers.
* **Tenancy** is built in: cgroup v2 limits and per-tenant accounting
  (`scalws-highcpu`, `scalws-limitram`, ...).
* **Operations** are built in too: an admin API, `scalwsctl diagnose`, the optimizer
  journal, and Prometheus metrics.
* **Apache features:** there are no Apache modules. Apache's `.htaccess` is supported for
  a common subset. See below.

**Performance.** The benchmark of the 1.0.0 release is
[../benchmarks/2026-11-12-xeon-1.0.0.md](https://scalws.com/docs/benchmarks/2026-11-12-xeon-100/).
More reports are in [the benchmark reports](https://scalws.com/docs/benchmarks/).

The setup of that run:

* One bare-metal machine with 2× Xeon E5-2650 v2. The server ran on six CPUs of one
  socket: the published 1.0.0 `.deb` under `scalws-controller`, three instances of two
  CPUs each, with the service sandbox on (what a new install gets).
* Load came from `oha` with 64 connections. 5 runs of 30 s each; the tables show medians.
* Two ScalWS columns: `defaults` (the package as installed) and `own HTTP/1`, which turns
  on both opt-in experimental settings: the own HTTP/1 server and the own upstream client.

The ratios to nginx 1.31.6, with the defaults (`own HTTP/1` in parentheses):

| Result | Scenarios |
|---|---|
| Ahead | cache hits 1.54× (1.70×), HTTPS/HTTP/2 small static files 1.29× (1.27×), PHP 1.06× (1.06×) |
| About level | small static files 0.98× (1.03×), 1 MB static files 0.99× (0.99×), Node.js 0.98× (0.96×), Python 0.97× (0.90×) |
| Behind | fixed responses 0.86× (0.93×), proxy 0.83× (0.98×) |

Peak server memory was 109 to 120 MiB for the controller and its three instances
together, against 103 to 131 MiB for nginx.

Keep these caveats in mind:

* **The gap with the default settings** on fixed responses and proxy comes from the default
  HTTP/1 server and client (hyper's); the report shows how it was measured.
* **These are one machine's results** for these synthetic scenarios, not a general
  guarantee.
* **LiteSpeed Enterprise is not in this run**: its trial licence had run out.

Read the report itself before you draw conclusions.

## Migration

### Can I move my nginx or Apache sites?

Yes. `scalwsctl migrate` reads the existing configuration (it is never modified) and writes
one ScalWS site file per virtual host:

```sh
sudo scalwsctl migrate nginx --dry-run      # /etc/nginx/nginx.conf and its includes
sudo scalwsctl migrate nginx
sudo scalwsctl migrate apache               # /etc/apache2/apache2.conf or /etc/httpd/conf/httpd.conf
```

It converts these directives:

* server names and aliases, and `www.` handling
* port-80 hosts that only redirect to HTTPS (into `https_redirect`)
* document roots and index files
* PHP-FPM `fastcgi_pass` and `SetHandler proxy:`
* `proxy_pass` and `ProxyPass`
* redirects
* `AllowOverride`, which becomes `htaccess: true`

Everything else is written into the site file as `# TODO:` lines with the source file and
line. The new files are checked together like a reload, and the whole run is undone if the
check or the reload fails.

Stop nginx or Apache only after `scalwsctl site list` shows every site. Then let ScalWS take
ports 80 and 443. See [../sites.md](https://scalws.com/docs/sites/).

### Do my `.htaccess` files work?

Yes, for the common directives, if you enable it per application with `htaccess: true`, or
`scalwsctl site add --htaccess`. ScalWS reads `.htaccess` files from the application's
root down to the requested directory. Edits take effect within 2 seconds.

Supported directives:

* mod_rewrite
* `Redirect` and `RedirectMatch`
* `Require` and `Order`/`Allow`/`Deny`
* `<Files>` and `<FilesMatch>`
* `ErrorDocument` and `DirectoryIndex`
* `Header` and `Expires`

Lines that are not supported or are refused are skipped and logged with the file name.
These include `php_value`, `[P]` proxy rules, `SetHandler`, and look-around regular
expressions. See [../OPERATIONS.md](https://scalws.com/docs/operations/#htaccess-adr-0031) and
[../adr/0031-htaccess.md](https://scalws.com/docs/adr/0031-htaccess/).

## Applications

### Can I run several PHP versions?

Yes, per application.

* **Managed pools** (`scalwsd.service`): set the PHP-FPM binary of each application, for
  example `php: {fpm: {binary: /usr/sbin/php-fpm8.2}}`. Without `binary`, ScalWS uses the
  first `php-fpm` found on `PATH`, else the newest versioned one (`php-fpm8.4`, `php-fpm84`).
* **External pools** (any setup, and the only option under scalws-controller): point each
  site at the socket of the PHP-FPM version it needs, for example
  `php: unix:/run/php/php8.2-fpm.sock` in one site and
  `php: unix:/run/php/php8.3-fpm.sock` in another.

See [applications.md](https://scalws.com/docs/guide/applications/).

### Are WebSockets supported?

Yes. Proxy runtimes tunnel WebSocket upgrades by default (`websocket: true` on the proxy).
Managed Node.js applications tunnel them too.

Upgraded connections are limited by `server.limits.max_upgraded_connections`, and closed
after `server.limits.upgraded_idle_timeout` without traffic. When an instance drains under
the controller, each tunnel gets a `1001 Going Away` close frame, so clients reconnect to an
instance that stays.

### Is HTTP/3 supported?

Yes. Every package (`.deb`, `.rpm`, `.apk`) includes HTTP/3, and it is off until you turn
it on: set `http3: true` on a TLS listener, reload (under `scalwsd.service`: restart), and
open UDP 443 in the firewall (the package does not). The commands are in
[installation.md](https://scalws.com/docs/guide/installation/#http3-udp-443), the setting in
[tls.md](https://scalws.com/docs/guide/tls/#http3-quic).

HTTP/3 works under scalws-controller through its QUIC demux, with the default
`listen: inherited`. It is refused with `listen: reuseport` and with `scalwsd --reuseport`.
Not supported over HTTP/3: WebSockets (they stay on HTTP/1.1 and HTTP/2) and 0-RTT.

A `scalwsd` built from source without `--features http3` refuses the setting:

```text
http3: true needs a build with the `http3` feature (cargo build --features http3)
```

See [../adr/0019-http3.md](https://scalws.com/docs/adr/0019-http3/) and
[../http3-multi-instance.md](https://scalws.com/docs/adaptive-runtime/http3-multi-instance/).

### Can it run containers?

Yes. `runtime: {type: container}` runs an image with podman (the default) or docker as a
supervised application. Install `podman` and `catatonit` on the host. With podman and cgroup
enforcement, containers run under the tenant's cgroup, so tenant limits include them.

Containers are a managed runtime, which has two consequences:

* they are refused under scalws-controller
* they are refused for tenants that have a Unix `user`

See [../OPERATIONS.md](https://scalws.com/docs/operations/#containers) and
[../adr/0020-container-runtime.md](https://scalws.com/docs/adr/0020-container-runtime/).

### Can I run ScalWS in Kubernetes?

Yes. It runs as the web server pod of an application ([Kubernetes](https://scalws.com/docs/guide/kubernetes/)), as an
[Ingress controller](https://scalws.com/docs/guide/ingress-controller/) and as a [Gateway API](https://scalws.com/docs/guide/gateway-api/)
implementation. Multi-node coordination of plain servers is not available; its design is in
[../adr/0021-multi-node-control-plane.md](https://scalws.com/docs/adr/0021-multi-node-control-plane/).

### Can ScalWS replace the web server of cPanel, DirectAdmin or Plesk?

Yes, on the systems each panel supports (see the
[panel and system matrix](https://scalws.com/docs/guide/control-panels/#panels-and-systems)). On a panel server the first install of the package switches the panel's web server to
ScalWS (`scalwsctl panel enable <panel>`; install with `--panel=none` to skip it). ScalWS
then serves the panel's domains, subdomains and aliases with their PHP versions, webmail and
certificates, and a panel change (a new domain, a renewed certificate, a suspension) reaches
it within seconds. `sudo scalwsctl panel disable` gives the ports back to the panel's web
server. See [Control panels](https://scalws.com/docs/guide/control-panels/).

## Configuration and operation

### Where does the configuration live?

| Path | Content |
|---|---|
| `/etc/scalws/scalws.yaml` | The server configuration (`0640 root:scalws`, kept on upgrade). |
| `/etc/scalws/sites.d/*.yaml` | One file per site, included by `include: sites.d/*.yaml`. |
| `/etc/scalws/controller.yaml` | scalws-controller's configuration. |
| `/etc/scalws/console/credentials` | ScalWS Console accounts (0600). |
| `/usr/share/doc/scalws/examples/scalws.yaml` | The full reference configuration. |
| `/var/lib/scalws` | ACME account and certificates. |
| `/var/lib/scalws-controller` | Configuration generations and instance logs (`logs/web-<n>.log`). |
| `/var/lib/scalws-console` | Console history, audit log and TLS material. |
| `/run/scalws/admin.sock` | Admin socket of `scalwsd.service`. Under the controller, each instance has `/run/scalws/web-<n>/admin.sock`. |

See [configuration.md](https://scalws.com/docs/guide/configuration/) and [../sites.md](https://scalws.com/docs/sites/).

### How do I apply a configuration change?

1. Run `sudo scalwsctl check`.
2. Reload:
   * under scalws-controller: `sudo scalws-controller reload`
   * with `scalwsd.service`: `sudo scalwsctl reload` or `systemctl reload scalwsd`

A reload that fails keeps the running configuration. `scalwsctl rollback` (on
`scalwsd.service`) or the console's history (under scalws-controller, which has no rollback
command) returns to an earlier configuration. Some changes need a restart; see
[configuration.md](https://scalws.com/docs/guide/configuration/#reload-or-restart).

### How do I see what is wrong?

Run `scalwsctl diagnose`, read the logs, and see [troubleshooting.md](https://scalws.com/docs/guide/troubleshooting/).

### Is there a web interface?

Yes: ScalWS Console, on `https://<host>:8090`. It manages the server through
scalws-controller. The installer creates the user `admin` with a random password, which is
stored in `/etc/scalws/console/credentials`. See
[../console-operations.md](https://scalws.com/docs/console/operations/). `scalwsd` also serves a read-only
dashboard at `/dashboard` on its loopback metrics listener.

### How do I back up a server?

```sh
scalwsctl backup /var/backups/scalws-$(date +%F)
```

This copies the configuration and the certificates and keys it references. Document roots
and application data are not included. To restore, run `scalwsctl restore <dir> --apply`.
Also back up `/var/lib/scalws-console` if you use the console.

## Licence

### Under which licence is ScalWS released?

The workspace manifest (`Cargo.toml`) and the package metadata declare `Apache-2.0`.
