nginx Compatibility

bext includes a production-ready nginx compatibility layer that reads your existing nginx.conf, parses every directive, and serves all traffic — no config rewrite needed.

At a Glance

- 97% directive coverage — 68 of 70 commonly used directives implemented

- 325+ tests — validated against 32 real-world production configs with 89 vhosts

- 13K–34K req/s — benchmarked in release mode

- Zero config changes — point bext at your nginx.conf and go

- FastCGI proxy to PHP-FPM — WordPress, Laravel, and Symfony sites work via existing PHP-FPM pools

- Automatic WordPress detection — detects wp-config.php / wp-content and configures routing

- SSL certificate expiry tracking — parsed from certificate files and reported in dashboards

- Cloud dashboard integrationbext nginx sync-cloud pushes all sites to cloud.bext.dev

- Agency / client site management — sites grouped by client in the cloud dashboard

How It Works

bext's nginx compatibility is a three-stage pipeline:

1. Parse — A recursive-descent parser reads nginx.conf (including all include directives with glob expansion) and builds an AST 2. Convert — The converter transforms nginx directives into bext's internal routing, caching, TLS, and security configuration 3. 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:

1. Host header routing — match the request to a server {} block 2. Access rules — evaluate allow/deny directives 3. Authentication — check auth_basic credentials 4. Rate limiting — enforce limit_req and limit_conn zones 5. Body size check — validate client_max_body_size 6. Conditionals — evaluate if blocks 7. Rewrite rules — apply rewrite and return directives 8. Location matching — find the best matching location {} block 9. Response pipeline — proxy, FastCGI, static file, or fixed response 10. 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 proxy → PHP-FPM socket Auto-detected via wp-config.php or wp-content/
Laravel FastCGI proxy → PHP-FPM socket Detected via artisan or public/index.php patterns
Symfony / Custom PHP FastCGI proxy → PHP-FPM socket 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

For PHP sites, bext proxies requests to your existing PHP-FPM pools — there is no embedded PHP. The PHP version is extracted from the socket name (e.g., php8.4-fpm.sock → 8.4) for reporting purposes.

Static assets (CSS, JS, images) are always served directly by bext, even on PHP sites, matching the typical 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/O

- worker_processes, worker_connections — bext uses async tasks, not process forking

- events {} — not applicable in an async runtime

- types {} — bext uses built-in MIME detection

- proxy_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.

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