High-performant webserver with Static files, C#, PHP-FPM, reverse proxy, and WASM support. 500K+
5.5K
This performance-focused, yet feature-rich webserver in dotNET 10 (.NET 10 / C#) utilizes Kestrel for the main webserver, a high-performance focused Csharp webserver library. JonCsWebServer is able to handle 80 000 to 800 000 req/s (or ~15-28 Gbps) on Intel Xeon E5-2680 V4 (2016 CPU!), it also comes with a lot of additional features compared to barebones Kestrel!
JonCsWebConfig.json to configure the webserver.--httpPort=80,8080 --httpsPort=443,8443 (multi-port support!).dll, rename to ._csdll. This is to avoid collisions with normal .dll-files.)._cs-files with raw C# code; webserver compiles live outside of request loop. Should have no performance loss.Read more on our open source GitHub and GitLab!
Simply replace HTTPd with JonCsWebServer, setup php-fpm, and keep using your setup with a huge performance boost. Be bottlenecked by your network setup, not your software. JonCsWebServer also matches Nginx in throughput, so unless you have use of more advanced Nginx features, you can just use JonCsWebServer.
Quick run command:
docker run -v /var/www:/var/www \
-v /path/to/config:/app/JonCsWebConfig.json \
-p 80:80 -p 443:443 -it \
jgtv/joncswebserver:linux-amd64
docker run -it -d --name joncsweb \
-p 80:80 -p 443:443 \
jgtv/joncswebserver:linux-amd64 \
--httpPort=80 \
--httpsPort=443
docker run -it -p 80:80 -p 443:443 jgtv/joncswebserver:windows
Tested and working:
jgtv/joncswebserver:linux-amd64
jgtv/joncswebserver:windows
Benchmarks (using k6 on the same machine) (without docker):
Benchmarks (using wrk on the same machine) (without docker):
For reference, Rust with barebones Actix reaches ~1.1m RPS on 2x Intel Xeon E5-2680 V4, and roughly double the sendFile throughput (490K rps instead of 200K. With no middleware like compression, etc)
The json below contains comments about what each option does. The out-of-the-box settings should be very similar.
DO NOT USE! IT WILL BREAK JSON SYNTAX.
{
"Logging": false, // will write errors to `joncserror.log`, useful when a C#-endpoint errors.
"DebugPages": false, // Show error pages (displays error as a html) when request errors. Recommended to only use during development and not on production.
"ServerMetrics": false, // Tracks total requests, and latest rps, rpm, rph
"LoopFindEndpoint": false, // If true, it tracks backwards until it finds an index (otherwise err404): /path1/path2/index.html -> /path1/path2 -> /path1 -> /
"EnableHtaccess": false, // .htaccess-support
"Enable_CS": true, // C#/._csdll-backend support
"Enable_WASM": false, // ._wasm-backend support
"AllowSynchronousIO": false,
"ForceTLS": false, // Force TLS when proxying?
"Rproxy_SslProtocol": "Tls13", // Set TLS-Protocol for Reverse-Proxy.
"BufferFastCGIResponse": false, // Tweak PHP performance depending on high/low scale
"Max_QUIC_Streams": 0,
"MaxConcurrentConnections": null, // Max global concurrent HTTP(S)-connections
"MaxConcurrentUpgradedConnections": 10000, // Max global concurrent WS(S)-connections
"MaxRequestBodySize": 8000000000, // Max POST-length
"HttpProxyTimeout": 300.0,
"bytesPerSecond": 1.0, // Minimum bytes-per-second before WebServer temporarily blocks user. Set it low to avoid false-positives from skimming through videofiles.
"gracePeriod": 5,
"MaxBytesPerSecond": 0, // Limit outbound bandwidth per-client-IP
"RequestTimeout": 0,
"KeepAliveTimeout": 130,
"RequestHeadersTimeout": 30,
"RateLimitTime": 1, // 1 second. CF default: 10
"RateLimitReq": 0, // Amount of requests within RateLimitTime before it ratelimits specific IP. Recommended: 500
"RateLimitRefill": 100,
"RateLimitQueue": 0,
"MaxFilePathLength": 512,
"FCGI_ReceiveTimeout": 300000,
"FCGI_SendTimeout": 300000,
"FCGI_MaxPoolSize": 20,
"FCGI_QueueTimeout": 10,
"FCGI_MaxConcurrentConnections": 5000,
"ClearSessEveryXMin": 5,
"WebSocketTimeout": 300,
"WebSocketEndpointTimeout": 30,
"MaxDirDepth": 15, // Max amount of slashes in the URL. /path1/path2/path3...
"HttpsPorts": [ // --httpsPort=443,8443
443, 8443
],
"HttpPorts": [ // --httpPort=80,8080
80, 8080
],
"CertDir": "certs/", // certs -> domain1, domain2 -> privkey.pem, fullchain.pem // override with --certPath=/etc/letsencrypt/live/
"WWWdir": "", // Static-files exclusive mode // --webPath=/var/www
"BackendDir": "www", // Hybrid mode (Static files + backend) // --backend=/var/www
"SessionsDir": "sess/", // Used in C#-endpoints for saving/loading sessions from.
"SessionCookieName": "SSID",
"Rand_Alphabet": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", // Letters used for randomizing i.e. SSID
"FilterFromDomain": "", // Optional: "."
"DomainFilterTo": "", // If set to "", it will replace all "." with ""
"indexPriority": [ // Every directory tries to "copy" endpoint from the first file found within this list
"index._csdll",
"index._cs",
"index.php",
"index._wasm",
"index.njs",
"index.bun",
"index.html"
],
"DownloadIfExtension": [ // These file extensions tell client to download (through headers)
"zip", "tar", "gz",
"jar", "apk",
"dll",
"exe", "bat", "bash", "sh", "x86_64"
],
"CompressionLevel": 0, // "Optimal" / 0, "Fastest" / 1, "NoCompression" / 2, "SmallestSize" / 3
"ExtTypes": { // Set headers per-file extension
"html,htm,xhtml": [
"Content-Type: text/html",
"Cache-Control: max-age=86400"
],
"php": [
"Content-Type: text/html"
],
"txt,log": [
"Content-Type: text/plain"
],
"css": [
"Content-Type: text/css"
],
"svg": [
"Content-Type: image/svg+xml"
],
"mp3": [
"Content-Type: audio/mpeg"
],
"js": [
"Content-Type: application/javascript"
],
"json": [
"Content-Type: application/json"
],
"pdf": [
"Content-Type: application/pdf"
],
"zip": [
"Content-Type: application/zip"
],
"jar": [
"Content-Type: application/jar"
],
"dll": [
"Content-Type: application/dll"
],
"exe": [
"Content-Type: application/exe"
],
"apk": ["Content-Type: application/vnd.android.package-archive"],
"wasm": ["Content-Type: application/wasm"],
"png": [
"Content-Type: image/png"
],
"jpeg,jpg": [
"Content-Type: image/jpeg"
],
"gif": [
"Content-Type: image/gif"
],
"webp": [
"Content-Type: image/webp"
],
"ico": [
"Content-Type: image/ico"
],
"wav": [
"Content-Type: audio/wav"
],
"ogg": [
"Content-Type: audio/ogg"
],
"mp4": [
"Content-Type: video/mp4"
],
"flv": [
"Content-Type: video/flv"
],
"mkv": [
"Content-Type: video/mkv"
],
"wmf": [
"Content-Type: video/wmf"
],
"avi": [
"Content-Type: video/avi"
],
"webm": [
"Content-Type: video/webm"
],
"srt,vtt": ["Content-Type: text/plain; charset=utf-8"]
},
"ForwardExt": { // Reverse-proxy and FastCGI-support
"njs": "http://{domain}:7001",
"bun": "http://{domain}:3000",
"php": "fcgi://127.0.0.1:9000"
},
"DefaultHeaders": { // Default headers for all non-404 requests
"Server": "JH",
"vary": "Accept-Encoding",
"Accept-Ranges": "bytes",
"Access-Control-Allow-Origin": "*",
"cache-control": "max-age=300"
},
"DomainAlias": { // Lead www.domain to domain, etc.
"www.example.com": "example.com",
"127.0.0.1": "localhost",
"www.jonhosting.com": "jonhosting.com",
"www.jontv.me": "jontv.me"
},
"UrlAlias": {
// "jonhosting.com/testing1234": "/test2_maybe_use_symlink_instead/useDomainAlias_for_changing_domain_virtually"
}
}
[] = optional
listfiles [path] | Lists full filePaths of every file that has been indexed.
countfiles [path] | Same as listfiles, but returns a number.
indexfiles [path] | Manually index from a directory. Can be useful in-case of any FileWatcher bugs.
clearcerts | Clears cached certificates
loadcerts | Loads certs (use clearcerts + loadcerts to reload certificates live)
listcerts | Lists domains that has certificates
reload | Reload from config file. You may want to use indexfiles after this if you changed ExtTypes or DownloadIfExtension
stats | Shows memory (RAM) and CPU usage. If ServerMetrics is turned on in config, it tells you total requests, and latest rps, rpm, rph.
gc | Manually force GC
shutdown | Shuts down the webserver
Content type
Image
Digest
sha256:6de06eece…
Size
200.3 MB
Last updated
about 2 months ago
docker pull jgtv/joncswebserver:windows