Deployment
A Blazor Web App using AdminLTE is a standard ASP.NET Core app. Publish it like any other .NET 10 site — the catch with the InteractiveServer render mode is that you must run behind a reverse proxy that supports WebSockets, because each user holds a persistent Blazor Server circuit.
Publish
For a portable, dependency-free deployment, publish self-contained for your target runtime:
dotnet publish -c Release -r linux-x64 --self-contained -o ./publish
Drop -r / --self-contained if the target host already has the .NET 10 runtime installed (a framework-dependent publish is smaller).
Publish to a clean directory (or delete the output folder first). Stale fingerprinted static assets from a previous publish can linger and be served instead of the current ones — the RCL's AdminLTE/Bootstrap files are versioned static web assets, so an old copy left behind causes hard-to-debug CSS/JS mismatches. Use a fresh -o folder each time.
Reverse proxy with WebSocket support
InteractiveServer keeps a SignalR/WebSocket connection open per user (the Blazor "circuit"). The reverse proxy in front of Kestrel must forward and upgrade WebSocket connections, or the UI will fail to go interactive and fall back / disconnect.
nginx
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
proxy_read_timeout 100s;
}
}
Pair this with app.UseForwardedHeaders(...) in Program.cs so the app sees the original scheme/host behind the proxy.
Run as a systemd service
Keep the app running and restart it on failure with a unit file:
# /etc/systemd/system/adminlte-app.service
[Unit]
Description=AdminLTE ASP.NET Core app
After=network.target
[Service]
WorkingDirectory=/var/www/adminlte-app
ExecStart=/var/www/adminlte-app/MyApp
Restart=always
RestartSec=5
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=ASPNETCORE_URLS=http://127.0.0.1:5000
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now adminlte-app
sudo systemctl status adminlte-app
Checklist
- Publish to a clean output directory to avoid stale static assets.
- Enable WebSocket upgrade in the reverse proxy (Blazor Server circuit).
- Forward
X-Forwarded-Proto/X-Forwarded-Forand callUseForwardedHeaders. - Terminate TLS at the proxy and keep
UseHttpsRedirectionaware of the forwarded scheme. - Confirm
MapStaticAssets()is serving/_content/ColorlibHQ.AdminLTE.AspNetCore/after deploy.
If you scale to more than one instance, Blazor Server requires sticky sessions (or a backplane) so a user's circuit always reaches the same server. A single instance behind one proxy needs no extra configuration.