Nginx Config for .netcore Blazor WebAssembly
I recently finished a few Blazor WebAssembly projects which was both fun and challenging. With a Blazor WebAssembly SPA app you end up creating a static html site that is interactive or dynamic based on the API calls. This means you can actually host the site on a static file system or something like S3 / CloudFront CDN and then the calling API functions can be on a traditional web server or container system.
However during development or a quick deployment, you may want to simply load it on the web-server, which is what I did. I used Ngnix to serve up both the static site (WebAssembly) and the web-api section. The following configuration was used and it worked like a charm.
# typically 1 per core
# determine cores
# --- linux: grep processor /proc/cpuinfo | wc -l
# --- mac: sysctl -n hw.ncpu
worker_processes 1;
error_log /var/log/nginx/error.log info;
events {
# check limit
# --- mac/linux: ulimit -n
worker_connections 1024;
}
http {
sendfile on;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
large_client_header_buffers 4 16k;
upstream app_servers {
# this must be the same name as the docker container name
# it's how it maps to the service
# you can actually add more than one here if you want to
# unless its in ECS then it's localhost
server web-api:5000;
}
server {
listen 80;
#listen [::]:80;
server_name $hostname;
client_max_body_size 10M; # upload size
# root handle blazor spa app
location / {
# location of the app (html files) in the container
# this is defined in the Dockerfile for the spa app
# or in the local file system if you have it published here
root /app/www;
# with a spa app we should redirect to /index.html on any not found pages
try_files $uri $uri/ /index.html =404;
include /etc/nginx/mime.types;
types {
application/wasm wasm;
}
default_type application/octet-stream;
# allow for gziped items in the framework path
location /_framework/ {
gzip_static on;
}
# cache buster
add_header Last-Modified __CACHE_BUSTER_EXPIRE_DATE_TIME; # this should be replaced by a shell script
add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
if_modified_since off;
expires off;
etag off;
}
# handle api requests which is in a different docker container
location /api {
proxy_pass http://app_servers; # references the upstream app_servers above
proxy_redirect off;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-NginX-Proxy true;
}
}
}
Image Credit: https://www.nginx.com/
Jens - Saturday, 20 March 2021
Getting Nginx to work with dotnet is not hard but it does require some tinkering. I run a Piranha-based little site myself with Nginx (on an RPi actually) and boy do I have to revisit my Nginx config from time to time. :) Nice site you got here, I'll be back for sure!