nginx Compatibility
bext reads your existing nginx.conf — every include, every server and location block — and serves the traffic itself. No config rewrite, no migration project. In masquerade mode it installs as the nginx service, so the same boxes that ran nginx yesterday run bext today and nothing upstream notices.
At a Glance
- 68 of 70 common directives — 97% coverage of the directives real configs actually use
- Validated against real configs — hundreds of parser and conversion tests, run over production
nginx.conffiles with dozens of vhosts - Zero config changes — point bext at your
nginx.confand go - Drops in as
nginx—systemctl reload nginx,nginx -t, certbot, and logrotate keep working unchanged (Masquerade Mode) - PHP, your way — proxy to your existing PHP-FPM pools, or run PHP in bext's embedded runtime and retire FPM entirely
- Automatic WordPress detection — recognizes
wp-config.php/wp-contentand wires up routing and static-file handling - SSL certificate tracking — expiry parsed from certificate files and surfaced in the dashboards
- Cloud sync —
bext nginx sync-cloudpushes every vhost to cloud.bext.dev, grouped by client for agency fleets
How It Works
bext's nginx compatibility is a three-stage pipeline:
- Parse — A recursive-descent parser reads
nginx.conf(including allincludedirectives with glob expansion) and builds an AST - Convert — The converter transforms nginx directives into bext's internal routing, caching, TLS, and security configuration
- Serve — bext's HTTP server handles all traffic using the converted config
# Auto-detect nginx.conf and serve
bext serve --nginx-compat
# Or specify a config path
bext serve --nginx-config /etc/nginx/nginx.conf
# Full masquerade — replace nginx entirely
bext nginx masquerade install
Request Flow
When a request arrives in nginx-compat mode, bext processes it through the same pipeline nginx would:
- Host header routing — match the request to a
server {}block - Access rules — evaluate
allow/denydirectives - Authentication — check
auth_basiccredentials - Rate limiting — enforce
limit_reqandlimit_connzones - Body size check — validate
client_max_body_size - Conditionals — evaluate
ifblocks - Rewrite rules — apply
rewriteandreturndirectives - Location matching — find the best matching
location {}block - Response pipeline — proxy, FastCGI, static file, or fixed response
- Output — headers, gzip compression, response body
Supported Features
| Category | Directives | Count |
|---|---|---|
| Core | server, listen, server_name, root, index, try_files, error_page, default_type, etc. |
17 |
| Proxy | proxy_pass, proxy_set_header, proxy_redirect, proxy_cache, etc. |
8 |
| Upstream | upstream, server, least_conn, ip_hash, hash, weight, backup |
7 |
| SSL/TLS | ssl_certificate, ssl_certificate_key, ssl_protocols, ssl_ciphers, ssl_stapling, etc. |
8 |
| Rewrite | rewrite, return, if, set |
4 |
| Gzip | gzip, gzip_types, gzip_comp_level, gzip_min_length, gzip_vary |
5 |
| FastCGI | fastcgi_pass, fastcgi_param, fastcgi_index |
3 |
| Headers | add_header, proxy_set_header |
2 |
| Access | allow, deny |
2 |
| Auth | auth_basic, auth_basic_user_file |
2 |
| Limits | limit_req_zone, limit_req, limit_conn_zone, limit_conn |
4 |
| Variables | map, geo |
2 |
| Logging | access_log, error_log, log_format |
3 |
| Other | autoindex, sub_filter, expires, stub_status |
4 |
Supported Site Types
bext handles every common site type found in production nginx configs:
| Site Type | How It Works | Detection |
|---|---|---|
| WordPress | FastCGI → PHP-FPM pool (or embedded PHP) | Auto-detected via wp-config.php or wp-content/ |
| Laravel | FastCGI → PHP-FPM pool (or embedded PHP) | Detected via artisan or public/index.php patterns |
| Symfony / Custom PHP | FastCGI → PHP-FPM pool (or embedded PHP) | Any fastcgi_pass directive |
| Node.js / Bun proxy | Reverse proxy → upstream | proxy_pass to http:// backend |
| Static sites | Document root serving | root directive with no proxy or FastCGI |
PHP works two ways, and bext picks based on your config:
- Proxy to your existing PHP-FPM pool — when a PHP
locationhas afastcgi_pass, bext honors it and forwards to that socket or address, exactly as nginx did. This is the true drop-in path: your FPM pools, OPcache, and PHP version are untouched. The version is read from the socket name (e.g.php8.4-fpm.sock→ 8.4) for reporting. - Embedded PHP runtime — bext also ships its own PHP SAPI (worker mode, OPcache; built in via the
phpfeature). When a PHPlocationmatches but declares nofastcgi_pass, bext executes PHP in-process, letting you retire PHP-FPM entirely. See Laravel and the PHP Micro-Framework.
Static assets (CSS, JS, images) are always served directly by bext, even on PHP sites — matching the usual nginx static-file location blocks.
What's Different
Nine nginx directives are intentionally not implemented because bext's architecture handles them automatically:
sendfile,tcp_nopush,tcp_nodelay— handled by the OS and Rust's async I/Oworker_processes,worker_connections— bext uses async tasks, not process forkingevents {}— not applicable in an async runtimetypes {}— bext uses built-in MIME detectionproxy_buffering,proxy_buffer_size— bext streams responses
Cloud Sync
Sync your nginx vhosts to the bext cloud dashboard as projects and domains — no manual setup needed:
bext nginx list # List vhosts with stable IDs
bext nginx diff --cloud-api-key $KEY # Compare nginx vs cloud state
bext nginx sync-cloud --cloud-api-key $KEY # Push all to cloud
bext nginx sync-cloud --only a282,5427 # Push selected vhosts only
Each vhost gets a stable 4-character hex ID derived from its domain list. The diff command classifies each as synced, new, drift (domain mismatch), or stale (in cloud but not nginx).
See CLI Reference for all flags.
The nine directives listed under "What's Different" are the only intentional gaps. Everything else in a typical production nginx.conf converts automatically — run bext nginx check to confirm before making any changes.
Next Steps
- Config Parser — how the parser works
- Directive Coverage — complete directive reference
- Migration Guide — step-by-step migration from nginx
- Masquerade Mode — full drop-in replacement with systemd
- Cache Purge API — nginx-compatible cache management
- Preflight Dashboard — web UI for pre-migration inspection
- Takeover Process — atomic traffic migration with rollback
Related
- Migration Guide: from nginx — structured checklist for moving a fleet
- PHP & PHP-FPM — FastCGI dispatch and the embedded PHP runtime
- WordPress Integration — auto-detected WP routing on top of nginx-compat
- Caching — TTL, stale-while-revalidate, and stampede guard
- TLS and HTTPS — how bext loads and hot-reloads certificates
Links
- nginx documentation — upstream reference for directive semantics