Reference
Value formats
This page lists the exact forms ScalWS accepts for sizes, durations, CPU quotas, socket addresses, names, domains and paths in scalws.yaml, site files and on the command line.
Units are case-sensitive. Spaces before and after a size, a duration or a CPU quota are ignored; names, domains and paths are taken as written.
Sizes
Used by byte sizes such as
server.limits.max_request_body_bytes,
server.cache.memory and
tenants[].resources.memory, and by
scalwsctl limit ram|io.
A size is either a YAML integer (bytes) or a string of digits followed by an optional unit. Spaces between the number and the unit are allowed, and a number without a unit is bytes.
| Unit | Bytes |
|---|---|
none, B | 1 |
KiB | 1024 |
MiB | 1024² (1 048 576) |
GiB | 1024³ |
TiB | 1024⁴ |
KB, kB | 1000 |
MB | 1000² |
GB | 1000³ |
TB | 1000⁴ |
Binary and decimal units both mean what they say: 10MB is 10 000 000 bytes, 10MiB is
10 485 760 bytes.
| Accepted | Rejected |
|---|---|
1048576, "512", 16KiB, 16 KiB, 4GiB, 10MB, 2kB | 1.5GiB (no fractions), -1 (no negative sizes), GiB (no number), 16kib, 16K, 16 kilobytes (unknown unit), a value that overflows 64 bits |
ScalWS writes sizes back (for example scalwsctl limit --persist) in the largest binary
unit that divides them exactly, such as 2GiB or 1536KiB, else in bytes (1000B).
scalwsctl limit io takes a rate as a size followed by /s, for example 20MiB/s.
The configuration schema used by ScalWS Console forms describes sizes with the units B,
KB, MB, GB, KiB, MiB and GiB only, so the console’s forms may not accept
TiB, TB or kB; use a smaller unit there.
Durations
Used by timeouts and intervals such as
server.limits.idle_timeout,
server.acme.renew_before and
tenants[].applications[].cache.default_ttl.
A duration is a string: a whole number directly followed by one unit.
| Unit | Meaning |
|---|---|
ms | milliseconds |
s | seconds |
m | minutes |
h | hours |
d | days |
| Accepted | Rejected |
|---|---|
500ms, 10s, 5m, 1h, 30d | 10 (a bare number has no unit), 10 s (space before the unit), 1h30m (one unit only), 1.5s (no fractions), 1w (unknown unit), 10S |
Some fields also limit the range, for example
server.ai.timeout must be between 1s
and 10m.
Durations in controller.yaml
controller.yaml uses plain integers instead:
instances.start_timeout,
drain_timeout, kill_grace, restart_window and the autoscaling windows and
autoscaling.cooldown are whole
seconds (drain_timeout: 30);
autoscaling.lag_saturated is whole
milliseconds (lag_saturated: 5).
CPU quotas
Used by tenants[].resources.cpu.
A CPU quota is a string: a whole number directly followed by %, in percent of one CPU.
100% is one full CPU, 400% is four.
| Accepted | Rejected |
|---|---|
50%, 200%, 400% | 4 (no %), 0% (must be greater than 0%), 1.5%, 200 % |
scalwsctl limit cpu takes the same form; there the % may be left out (50).
CPU lists in controller.yaml
instances.cpus is a string of CPU numbers
and ranges separated by commas, for example "0-5", "0,2,4" or "0-3,6". A range
a-b needs a <= b and b < 4096.
Socket addresses
Used by server.listeners[].address,
server.metrics.address and
server.admin.remote.address,
and by scalwsctl --address, scalwsd --metrics-address and scalws-console --listen.
A socket address is an IP address and a port, with no host names:
| Form | Example |
|---|---|
| IPv4 address and port | 127.0.0.1:8080, 192.0.2.10:443; 0.0.0.0:443 listens on every IPv4 address |
| IPv6 address in brackets and port | [::]:443 listens on every IPv6 address |
Quote them in YAML (address: "127.0.0.1:8080"). Port 0 lets the operating system pick
a free port. Two listeners may not use the same address, and a listener may not use the
metrics address.
FastCGI addresses
php.fastcgi
and scalwsctl site add --php-fastcgi take unix: followed by an absolute path
(unix:/run/php/php8.3-fpm.sock) or tcp:host:port with a port from 1 to 65535
(tcp:127.0.0.1:9000). tcp:9000 is rejected.
Upstream URLs
proxy.upstream
takes http://host[:port], https://host[:port] or unix:/absolute/path. The host is a
name, an IPv4 address or an IPv6 address in brackets; the port defaults to 80 or 443 and
may not be 0. A path other than / and user information (user@) are rejected: requests
keep their original path.
Networks
server.trusted_proxies entries are an
IP address (192.0.2.10, one host) or a network in CIDR form (192.0.2.0/24). The prefix
is at most 32 for IPv4 and 128 for IPv6. Host names are rejected.
Names
Tenant names (tenants[].name), application
names (tenants[].applications[].name)
and listener names (server.listeners[].name)
appear in metrics, logs and cgroup paths, so they are restricted:
- 1 to 63 characters;
- only
a-z,0-9,-and_; - the first character is a letter
a-z.
| Accepted | Rejected |
|---|---|
shop, blog-example-com, api_v2 | Shop (upper case), 1password (starts with a digit), -shop, shop.example (dot), a name of 64 characters |
Listener names must be unique, and application names must be unique within their tenant.
When a site file sets no tenant or name, ScalWS derives them from the domain: lower
case, every run of other characters becomes one -, leading and trailing - are dropped,
s- is put in front when the result does not start with a letter, and the result is cut to
59 characters. shop.example.com becomes shop-example-com, 1password.com becomes
s-1password-com.
The instance id of scalwsd --instance-id is 1 to 32 characters of a-z, 0-9 and
-.
Domains
Used by tenants[].applications[].domains,
server.listeners[].tls.certificates[].server_names,
and the domain and
aliases of a site file.
A domain is normalized before it is checked and compared:
- letters are lower-cased (
Example.COMisexample.com); - trailing dots are removed (
example.com.isexample.com).
The result must be at most 253 characters (without a leading *.) and consist of labels
separated by dots. Each label is 1 to 63 characters of a-z, 0-9 and -, and does
not start or end with -.
A leading *. makes a wildcard that covers exactly one label: *.example.com matches
shop.example.com but not example.com or a.shop.example.com. The part after *. must
have at least two labels.
| Accepted | Rejected |
|---|---|
example.com, Shop.Example.COM., localhost, 127.0.0.1, *.example.com, xn--bcher-kva.example | a..b (empty label), -a.example (label starts with -), a_b.example (underscore), foo.*.example (* not first), *.com (wildcard over one label), bücher.example (use punycode), an empty string |
Internationalized domain names must be written in punycode (xn--...). A domain may be
served by only one application across the main file and all site files; the check reports
domain "<name>" is already used by <tenant>/<app>. A server name may be assigned to only
one certificate per listener.
Paths
Fields that name a directory or a file to serve must be absolute paths:
tenants[].applications[].root,
the root of the static and PHP runtimes, the Python runtime’s
virtualenv,
and PHP’s fpm.binary.
A path starting with / is accepted on every platform, so a configuration can be checked
on another machine; the server checks that the path exists when it prepares the
configuration. Otherwise the check reports <path> must be an absolute path.
include entries are relative to the directory of
the main configuration file. An entry may contain one *, and only in the file name
(sites.d/*.yaml); a * in a directory part and an entry that names a directory are
rejected.