Nginx Build & Modules
nginx binary management (RPM or WSA build), HTTP/3, Brotli compilation and configuration.
The Nginx Build & Modules page centralizes management of the nginx binary and its dynamic modules — Brotli and HTTP/3. This is where the administrator:
- Chooses between the
nginxpackage from the standard RPM repository or a custom WSA build (with HTTP/3). - Compiles and enables Brotli compression.
- Enables or disables QUIC emission (HTTP/3) on SSL vhosts.
- Monitors pinned versions against installed versions.
Access: Sidebar → Nginx Build & Modules.
⚠️ Actions on this page modify the nginx binary or recompile modules. They take several minutes and may briefly interrupt the service. Preferably execute outside peak hours.
1. Tab organization
The page is divided into 2 tabs:
[ Nginx | Brotli ]
| Tab | Content |
|---|---|
| Nginx | nginx binary choice, HTTP/3, QUIC, pinned versions. |
| Brotli | Brotli module install/rebuild, compression settings. |
2. Nginx tab

2.1 Nginx binary section
2.1.1 Current build
Current build
Where the running /usr/sbin/nginx came from.
┌──────────────────────────────────────────────────────┐
│ [ WSA custom build · 1.30.1 ] │
│ Compiled with --with-http_v3_module + bundled │
│ QuicTLS. │
│ RPM preserved at /usr/sbin/nginx.upstream.bak │
│ [ Revert to RPM ] │
└──────────────────────────────────────────────────────┘
Displays the origin of the currently running nginx binary:
| State | Display |
|---|---|
| WSA custom build · 1.30.1 | Custom WSA build, contains HTTP/3 and QuicTLS. The standard RPM is preserved as backup. |
| Stock RPM · 1.30.0 | Standard nginx binary from the RPM repository. No HTTP/3. |
Button Revert to RPM (visible only in WSA custom build mode) — Restores the standard RPM package:
- Disables HTTP/3 (SSL vhosts remove
listen 443 quic;). - Restores
/usr/sbin/nginx.upstream.bak→/usr/sbin/nginx. - Rebuilds configurations.
- Reloads nginx.
⚠️ Asks confirmation: "Roll back to the stock RPM nginx? The custom build will be removed and the original /usr/sbin/nginx.upstream.bak restored."
2.1.2 Update available
Update available
Cached daily by the checkNginxUpgrade cron — no
synchronous dnf check on page load.
┌──────────────────────────────────────────────────────┐
│ [ Update → 1.30.2 ] [ Upgrade nginx ] │
└──────────────────────────────────────────────────────┘
Detection of a new nginx version available via dnf. Detection runs daily in background (cron checkNginxUpgrade) — no synchronous dnf probe on page load.
State Up to date: green pill, no button.
State Update available: yellow pill with target version
- Upgrade nginx button:
- Launches a streamed
dnf upgrade nginx. - Recompiles Brotli automatically (the module is linked to nginx ABI — an upgrade would break Brotli without this step).
- Reloads nginx.
⚠️ Asks confirmation: "Run WSA-managed nginx upgrade? Will rebuild Brotli automatically."
💡 The Tier 2 mechanism (
dnf versionlocklock) preventsdnf-automaticupdates from replacing the WSA custom build binary without this procedure. That's why upgrade-via-WSA is the only correct way to advance versions.
2.1.3 HTTP/3 build
HTTP/3 build
Replace /usr/sbin/nginx with the WSA HTTP/3 binary,
or roll back to the upstream RPM.
┌──────────────────────────────────────────────────────┐
│ Installed │
│ [ Rebuild ] [ Revert to RPM ] │
└──────────────────────────────────────────────────────┘
Management of the custom HTTP/3 build. 3 possible states:
State 1 — HTTP/3 not installed (binary = standard RPM)
Single button: Build HTTP/3.
Starts the streamed compilation:
- Download nginx + QuicTLS from official sources.
- SHA256 verification (tarball integrity).
- Compilation (~3 to 8 minutes depending on server).
nginx -ttest on the new binary.- RPM backup at
/usr/sbin/nginx.upstream.bak. - Switch active binary to the new build.
- Open UDP/443 port (CSF or firewalld detected).
- Reload nginx.
⚠️ Asks confirmation: "Build the WSA HTTP/3 nginx? Takes 3-8 minutes; the stock RPM stays running until the new binary passes nginx -t."
State 2 — HTTP/3 installed and up to date
Two buttons:
- Rebuild — Rebuilds even if no pinned version change. Useful after a manual pin change or to force a new build.
- Revert to RPM — Uninstalls the HTTP/3 build and restores the standard RPM package. Also disables QUIC on vhosts.
State 3 — Not supported on this server
Neutral pill "Not supported on this OS" with reason (e.g., "EL 8 requires manual OpenSSL 3.0 backport — not automated"). The button is disabled.
HTTP/3 requires EL 9 or EL 10. EL 7 and EL 8 are not supported.
2.1.4 QUIC emission (visible only when HTTP/3 installed)
QUIC emission (Default: 0)
When On, every SSL vhost gets listen 443 quic; + Alt-Svc,
and UDP/443 is opened.
[ OFF ] ↺
Type: toggle Default: Off
When On, WSA adds listen 443 quic; and Alt-Svc header to SSL vhost configurations. Visitors on modern browsers automatically switch to HTTP/3; others stay on HTTP/2.
When Off, the HTTP/3 binary is installed but no vhost emits QUIC. Useful for:
- Testing the build before enabling in production.
- Temporarily disabling HTTP/3 without uninstalling the build.
Enabling or disabling triggers a full vhost rebuild followed by an nginx reload — output streamed live in a Process status view.
2.1.5 Pinned versions (table)
Pinned versions
What the current WSA release will build, vs. what is
actually built.
┌───────────────┬──────────────────────┬──────────────────┐
│ Component │ Pinned │ Built │
├───────────────┼──────────────────────┼──────────────────┤
│ nginx │ 1.30.1 │ 1.30.1 │
│ QuicTLS │ openssl-3.0.15-quic1 │ openssl-3.0.15-quic1 │
│ ngx_brotli │ a71f9312c2de │ a71f9312c2de │
└───────────────┴──────────────────────┴──────────────────┘
Compares pinned versions (what the current WSA release wants to build) with versions actually built on this server.
| Column | Source |
|---|---|
| Pinned | HTTP3_* constants in lib/bootstrap.php (updated each WSA release). |
| Built | SQLite state http3_state (updated on each successful HTTP/3 compilation). |
A divergence indicates that the build is stale — a WSA update bumped a pin but the server hasn't recompiled yet. The Brotli tile on the dashboard and the alert banner flag this case with a Rebuild CTA.
If fields are empty (—), HTTP/3 has never been built on this server (current binary = standard RPM).
3. Brotli tab

3.1 Status
Status
Brotli compresses text ~15-25% smaller than gzip.
Loaded as a dynamic .so.
┌──────────────────────────────────────────────────────┐
│ [ Active ] │
│ built for nginx 1.30.0 │
└──────────────────────────────────────────────────────┘
4 possible states:
| State | Pill | Meaning |
|---|---|---|
| Active | Green | Compiled, enabled, serving compressed responses. |
| Installed, disabled | Neutral | Compiled and loaded, but master switch brotli_enable=0. |
| Rebuild needed | Yellow | Compiled for an older nginx version (ABI drift). |
| Not installed | Red | No Brotli build on this server. |
Sub-line: nginx version Brotli was compiled for (built for nginx 1.30.0).
3.2 Build / rebuild
Build / rebuild
Compiles ngx_brotli against the current nginx headers.
Takes 2-5 min.
┌──────────────────────────────────────────────────────┐
│ [ Rebuild ] [ Uninstall ] │
└──────────────────────────────────────────────────────┘
3 buttons depending on state:
State 1 — Not installed
Install Brotli — Compiles and installs the module:
- Download ngx_brotli source (
git cloneatHTTP3_NGX_BROTLI_COMMIT). - Compile against current nginx version headers (~2 to 5 minutes).
- Install the
.soin/etc/nginx/modules/. - Add
load_moduleto main config. - Reload nginx.
State 2 — Installed
- Rebuild — Recompiles against the current nginx version. Useful after an nginx upgrade to avoid ABI drift.
- Uninstall — Removes the
.somodule, removesload_module, reloads nginx.
State 3 — Not eligible
Cannot install pill with reason (e.g., "Nginx 1.30.0 is too old, minimum 1.30.0", "Distribution not supported", etc.).
3.3 Compression configuration (visible when Brotli installed)
Four detailed parameters:
3.3.1 Enable Brotli compression
Enable Brotli compression [ OFF ]
Globally enable / disable Brotli emission.
(Default: Disabled)
Field: brotli_enable Type: toggle Default: Off
Global master switch. When Off, the module stays loaded but emits no Brotli compressed response (visitors will receive gzip if enabled, otherwise uncompressed).
3.3.2 Brotli compression level
Brotli compression level (0-11) (Default: 4)
Higher is smaller but slower.
[ 4 ] ↺
Field: brotli_comp_level Type: integer 0–11 Default: 4
| Level | Trade-off |
|---|---|
| 0 | No compression. Testing only. |
| 1–3 | Very fast, minimal compression. Negligible CPU. |
| 4 (default) | Excellent speed/ratio compromise. |
| 5–6 | More compressed, ~10–20 % more CPU. |
| 7–9 | High compression, non-negligible CPU. |
| 10–11 | Maximum, very slow. Appropriate only with pre-compressed .br serve. |
Recommendation: 4 for on-the-fly compression. 11 if using serve .br (static pre-compression).
3.3.3 Brotli minimum length
Brotli minimum length (bytes) (Default: 256)
Do not compress responses smaller than this.
[ 256 ] ↺
Field: brotli_min_length Type: integer (bytes) Default: 256
Threshold below which responses are not compressed. Compressing very small payloads costs more in CPU than the size gain.
Recommendation: 256 is the balanced default. Increase to 1024 or 2048 on CPU-limited servers.
3.3.4 Serve pre-compressed .br files
Serve pre-compressed .br files [ ON ]
If a sibling .br file exists, send it without
compressing on the fly.
(Default: Enabled)
Field: brotli_static_enable Type: toggle Default: On
When a pre-compressed .br file exists next to the original (style.css + style.css.br), nginx serves it directly instead of compressing on the fly.
No downside — pure gain when the customer's build tools generate .br (Webpack with CompressionPlugin({ algorithm: 'brotliCompress' }), WordPress plugin, etc.).
4. Footer and saving
4.1 Brotli config save
Save configuration button at the bottom of the Brotli tab (visible only when the module is installed). Saves the 4 Brotli settings (enable / level / min_length / static), then reloads nginx.
4.2 QUIC toggle save
Save configuration button at the bottom of the Nginx tab (visible only when HTTP/3 is installed). Saves the QUIC emission toggle value, then launches the streamed vhost rebuild.
4.3 Action buttons (Build, Upgrade, Revert)
These buttons don't require a Save — they directly trigger their action on click (with modal confirmation for destructive actions).
5. Internal architecture (informative)
5.1 Source of pinned versions
Hard-defined in src/lib/bootstrap.php:
define('HTTP3_NGINX_VERSION', '1.30.1');
define('HTTP3_NGINX_SHA256', '99765000d97...');
define('HTTP3_QUICTLS_TAG', 'openssl-3.0.15-quic1');
define('HTTP3_NGX_BROTLI_COMMIT', 'a71f9312c2deb28875acc7bacfdd5695a111aa53');
These constants are bumped each WSA release when the Astral Internet team validates a new upstream version.
5.2 Local state
Persisted in the options table of /etc/wsa/conf/wsa.sqlite:
| Key | Content |
|---|---|
http3_state |
JSON: {nginx_version_built, quictls_tag_built, ngx_brotli_built, binary_sha256, built_at, wsa_version_built} |
http3_enable |
0 or 1 — QUIC emission toggle state |
http3_auto_rebuild |
0 or 1 — auto-rebuild when pins move (CLI only today) |
brotli_enable |
0 or 1 |
brotli_comp_level |
0 to 11 |
brotli_min_length |
integer |
brotli_static_enable |
0 or 1 |
6. Further reading
- Dashboard — Overview including Brotli and HTTP/3 tiles.
- Release notes — History of security pin bumps (nginx CVEs, etc.).
- What is WSA? — Conceptual explanation of HTTP/3 and Brotli.
- Command line —
wsa --http3-*andwsa --nginx-*commands.