The config file says what to serve. Environment variables tune the server itself. They are read once, when the process starts, so a change needs a restart, not a reload.
Set them in a systemd drop-in (systemctl edit xtq-web), in /etc/xtq-web/env (one NAME=value per line, read by the packaged unit and passed to the container by the Docker installer), or with docker run -e or --env-file. The installer creates /etc/xtq-web/env with mode 600 if it does not exist yet.
Numbers are plain integers. Switches are on with 1 and off with 0. A value that can't be read as the expected type is ignored without a warning and the default is used, so XTQW_ACME=true leaves automatic HTTPS off. Write XTQW_ACME=1.
Config and process
| Variable | Default | Meaning |
|---|---|---|
XTQW_CONFIG |
unset | Path of the config file. Unset means environment-only mode |
XTQW_THREADS |
one per CPU | Worker threads |
XTQW_BLOCKING_THREADS |
64 |
Helper threads for disk reads and other blocking work |
XTQW_DRAIN_SECS |
10 |
Seconds open connections get to finish their request on SIGTERM or SIGINT. 0 exits at once. See Operations |
Connections
| Variable | Default | Meaning |
|---|---|---|
XTQW_MAX_CONNS |
16384 |
Open client connections. Capped at half the open-file limit |
XTQW_MAX_HANDSHAKES |
2 per CPU | TLS handshakes running at once. At least 1 |
XTQW_HANDSHAKE_WAIT_MS |
800 |
Milliseconds a new TLS connection waits for a handshake slot before it is closed |
XTQW_HEADER_TIMEOUT |
10 |
Seconds for the TLS handshake, and for an HTTP/1.1 client to send its request headers |
XTQW_MAX_TUNNELS |
16384 |
Open WebSocket and other upgraded connections, for the whole server |
See Protection.
TLS and certificates
| Variable | Default | Meaning |
|---|---|---|
XTQW_CERT |
unset | PEM certificate chain for the fallback certificate. Needs XTQW_KEY |
XTQW_KEY |
unset | PEM private key for XTQW_CERT |
XTQW_TLS_NAMES |
localhost |
Comma-separated names for the self-signed fallback certificate, used when XTQW_CERT and XTQW_KEY are not both set |
XTQW_ACME |
0 |
1 gets and renews Let's Encrypt certificates |
XTQW_ACME_DIR |
/var/lib/xtq-web/acme |
Where the account and certificates are stored |
XTQW_ACME_STAGING |
0 |
1 uses Let's Encrypt's staging service, stored in <dir>/staging |
XTQW_ACME_HOSTS |
every exact hostname | Comma-separated hostnames to get certificates for, replacing the list taken from the sites |
See HTTPS.
Admin and identity
| Variable | Default | Meaning |
|---|---|---|
XTQW_ADMIN_TOKEN |
unset | Unlocks /.xtq/dashboard, /.xtq/stats.json and /.xtq/metrics. Must be at least 16 characters, or they stay off |
XTQW_SERVER_HEADER |
xtq-web |
The Server header on every response. off leaves the app's own |
XTQW_POWERED_BY |
xTQ |
The X-Powered-By header on every response. off leaves the app's own |
XTQW_PROBE_MEMES |
on | 0 answers scanner probes with a plain 404 Not Found instead of a short note. Any other value keeps the note |
See Operations.
Cache
Shared by the PHP page cache and the files memory cache.
| Variable | Default | Meaning |
|---|---|---|
XTQW_CACHE |
1 |
0 turns off the page cache and the file memory cache |
XTQW_CACHE_MB |
1024 |
Memory for both, in MB |
XTQW_CACHE_TTL |
10 |
Seconds a cached PHP page is fresh |
XTQW_CACHE_STALE |
86400 |
Seconds past that a PHP page may still be served while a new copy renders |
Browser check
Used by challenge routes and by php sites.
| Variable | Default | Meaning |
|---|---|---|
XTQW_SECRET |
random | Key that signs challenges and pass cookies. Without it, a new random key is made at every start and reload, and every visitor has to pass again |
XTQW_POW_BITS |
18 |
Proof-of-work difficulty in zero bits, kept between 8 and 28. Each extra bit doubles the work for the browser |
See Protection.
PHP sites
These affect only php handlers. See Handlers.
| Variable | Default | Meaning |
|---|---|---|
XTQW_CHALLENGE |
1 |
0 turns off the built-in browser check and the per-address limit for php sites. challenge routes are not affected |
XTQW_OVERLOAD_BUSY_PCT |
90 |
Busy workers, in percent, at which xTQ PHP counts as overloaded |
XTQW_OVERLOAD_QUEUE_PCT |
60 |
Queue fill, in percent, at which xTQ PHP counts as overloaded |
XTQW_PER_IP_SLOTS |
4 |
Requests one client address may have in PHP at once |
XTQW_UPSTREAM_SLOTS |
0 |
Requests let into PHP at once. 0 learns it from xTQ PHP (its workers plus its queue), starting at 64 |
XTQW_EDGE_WAIT_MS |
3000 |
Milliseconds a request waits at the edge for room in PHP |
XTQW_PRIORITY_WAIT_MS |
10000 |
The same for visitors with a browser check pass |
XTQW_UPSTREAM_TIMEOUT |
120 |
Seconds xTQ PHP may take to answer |
XTQW_UPSTREAM_IDLE |
1024 |
Idle connections kept open to xTQ PHP, per site |
XTQW_UPSTREAM_MAX_BODY |
268435456 |
Largest response accepted from xTQ PHP, in bytes (256 MB) |
XTQW_MAX_BODY |
67108864 |
Largest request body passed to xTQ PHP, in bytes (64 MB). Larger gets 413 |
XTQW_BODY_TIMEOUT |
60 |
Seconds a client has to send its request body to a PHP site. Slower gets 408 |
XTQW_DENY |
unset | Comma-separated path prefixes, each starting with /, answered 403 Forbidden on php sites |
XTQW_STATIC_404 |
0 |
1 answers a missing file with an asset extension under a php docroot with a quick 404, instead of a PHP render |
XTQW_MAX_BODY and XTQW_BODY_TIMEOUT do not apply to proxy, which streams request bodies. A proxy pool has no size limit unless you set max_body in its block.
Environment-only mode
When XTQW_CONFIG is not set, xTQ Web does not read a config file. It serves PHP sites described entirely by the environment, the way xTQ PHP deployments were set up before the config file existed. The startup line then says config=environment. xtq-web check needs a file and does not work in this mode.
| Variable | Default | Meaning |
|---|---|---|
XTQW_HTTP |
0.0.0.0:80 |
Plain HTTP listener. off or empty turns it off |
XTQW_HTTPS |
0.0.0.0:443 |
TLS listener. off or empty turns it off |
XTQW_SITES |
unset | A file listing PHP sites, see below |
XTQW_UPSTREAM |
/run/xtq/php.sock |
xTQ PHP socket for the single site used when XTQW_SITES is not set |
XTQW_DOCROOT |
unset | Docroot for that single site |
XTQW_TRUST_CLOUDFLARE |
on | Trust Cloudflare's ranges for X-Forwarded-For. 1 or unset is on, any other value is off |
XTQW_TRUSTED_PROXIES |
unset | Comma-separated addresses and CIDR ranges to trust as well. Loopback is not trusted in this mode unless you list it here |
The XTQW_SITES file has one site per line: one or more hostnames, then the socket, then the docroot, or - for none. # starts a comment.
example.com www.example.com /run/xtq/example.sock /var/www/example
shop.example.com /run/xtq/shop.sock -
A hostname no line lists goes to the first site. SIGHUP reads the file again.
