Blazor VPS hosting
Blazor Server hosting on UpCloud with Nginx and HTTPS
Use this guide when a small Blazor Server app needs its own Ubuntu VPS instead of a managed platform. It covers the real work: DNS, SSH, .NET, Nginx, TLS, service restarts, backups, and the ongoing cost of owning the server.
The starting point is a simple UpCloud server at approx. $3/month. That can be enough for a modest production launch, but only if you keep patching, monitoring, log rotation, and rollback habits simple and repeatable.
UpCloud promo note: you and we each receive $29 in credits. Your monthly server price is not increased by the referral link.
Quick answer
Use a VPS when control matters more than platform comfort
A small UpCloud VPS is a good fit when you want stable costs, full Linux access, custom Nginx rules, direct logs, and a deployment flow you can inspect. It is a poor fit when you do not want to patch Ubuntu, watch disk space, test backups, or debug systemd at awkward times.
Fit check
A cheap Blazor VPS is useful only when the operating work is acceptable
The server price is not the whole decision. Count the time for updates, firewall rules, certificates, restores, logs, monitoring, and failed deploys before you choose self-hosting for a production app.
Choose this path when you want control
- You want full control over Nginx, systemd, SSH, logs, files, and runtime versions.
- The app is modest enough to start on a small VPS and scale later from a snapshot or rebuild.
- You can handle Ubuntu updates, firewall rules, certificates, backups, restores, and monitoring.
- You need predictable monthly infrastructure costs more than managed platform convenience.
Choose managed hosting when operations are the risk
- No one owns patching, backups, uptime checks, disk pressure, or incident response.
- The app needs managed scaling, managed databases, deployment slots, and platform support from day one.
- Non-technical teammates must deploy and recover the app without touching Linux.
- A short outage would be more expensive than a managed hosting bill.
Table of Content
Before setup
Prepare domain, DNS, SSH, .NET, Nginx, and TLS decisions first
Most failed VPS launches are not caused by Blazor. They happen because DNS is not ready, SSH access is unclear, ports are blocked, the app path is improvised, or certificate setup starts before the domain points at the server.
Point DNS before TLS
Create the A or AAAA record for the final host name before running Certbot. Certificate validation needs the public name to resolve correctly.
Use SSH keys and a deploy user
Start with key-based access, avoid routine root uploads, and decide which user owns the app directory before the first release.
Choose where publishing happens
Install the ASP.NET Core runtime on the VPS. Add the full .NET SDK only when you intentionally build or publish on the server.
Server plan
Start with the approx. $3/month server only when the app is modest
The smallest plan is a launch baseline, not a promise. It works best for low to moderate traffic, mostly static assets behind Nginx, lightweight database use elsewhere, and a team that can scale before memory or CPU pressure becomes user-visible.
- Use it for
- Small production apps, staging apps, internal dashboards, prototypes with real users, and low-traffic content sites.
- Avoid it for
- Memory-heavy apps, noisy background jobs, large local databases, high traffic spikes, or teams without server maintenance time.
- Upgrade signal
- Scale when swap usage, CPU saturation, queue delays, or restart frequency becomes visible in logs and user timings.
Create the server
Choose the nearest useful region, a clean Ubuntu image, SSH keys, and the smallest plan that matches your launch risk.
Lock the network
Allow SSH, HTTP, and HTTPS. Keep databases, dashboards, and app ports private unless there is a specific reason.
Take a baseline snapshot
Snapshot the server after hardening and before the first production deploy so rebuilds are faster and less stressful.
Document the rebuild
Keep the DNS, package, firewall, app path, service name, and certificate steps in a short runbook.
Server setup
Patch Ubuntu, keep the public surface small, and install .NET deliberately
Start from a clean Ubuntu image. Apply updates, keep timestamps predictable, install only the packages you need, and open just SSH, HTTP, and HTTPS. The SDK is optional on the server when you publish from your workstation or CI.
Base packages
sudo apt update && sudo apt upgrade -y
sudo apt install -y curl wget unzip apt-transport-https ca-certificates gnupg
sudo timedatectl set-timezone UTCFirewall and fail2ban
sudo apt install -y ufw fail2ban
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https
sudo ufw enable
sudo systemctl enable --now fail2ban.NET packages
wget https://packages.microsoft.com/config/ubuntu/24.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
rm packages-microsoft-prod.deb
sudo apt update
sudo apt install -y aspnetcore-runtime-8.0Deploy flow
Publish locally, upload predictably, and let systemd own the app process
For a small server, the safest manual deploy is simple: build a Release output, upload it to a known directory, run the app as a dedicated user, and make systemd responsible for restart behavior and logs.
Publish and upload
# Build locally
dotnet publish -c Release -o publish
# Copy to UpCloud (replace user@host)
rsync -avz --delete publish/ user@YOUR_UPCLOUD_IP:/var/www/blazor-app/releases/current/
# On the server, set ownership
sudo useradd -m -s /bin/bash blazorapp || true
sudo chown -R blazorapp:blazorapp /var/www/blazor-appsystemd service
[Unit]
Description=Blazor Server on UpCloud
After=network.target
[Service]
User=blazorapp
WorkingDirectory=/var/www/blazor-app/releases/current
ExecStart=/usr/bin/dotnet /var/www/blazor-app/releases/current/YourApp.dll --urls http://127.0.0.1:5001
Restart=always
RestartSec=5
Environment=ASPNETCORE_URLS=http://127.0.0.1:5001
[Install]
WantedBy=multi-user.targetNginx and TLS
Put Kestrel behind Nginx and make HTTPS the only public path
Kestrel should listen on localhost. Nginx receives public traffic, redirects HTTP to HTTPS, terminates TLS, forwards the original host and protocol, and keeps the URL stable for users and search crawlers.
Nginx reverse proxy
server {
listen 80;
listen [::]:80;
server_name app.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name app.example.com;
ssl_certificate /etc/letsencrypt/live/app.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
location / {
proxy_pass http://127.0.0.1:5001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
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-Proto $scheme;
proxy_cache_bypass $http_upgrade;
}
}Certbot commands
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d app.example.com --redirect --agree-tos -m [email protected]
sudo certbot renew --dry-runOperations
Keep costs honest by planning maintenance before traffic arrives
The monthly VPS bill is predictable. The operations cost is not unless you make it routine: maintenance windows for patching, certificate renewal checks, log rotation, disk alerts, snapshots, restore tests, and a short rollback process for failed releases.
Patch on a schedule
Run package updates during a planned window, then check the Blazor service, Nginx status, and certificate renewal path.
Test restore, not just snapshot creation
Snapshots are useful only when you have restored one. Keep app files, secrets, and database backups in the recovery plan.
Watch for quiet failures
Use journalctl, Nginx logs, disk alerts, and uptime checks so failed deploys or bot traffic do not stay invisible.
Scale before users feel it
Move to a larger plan, split services, add a CDN, or clone from a snapshot before memory pressure becomes downtime.
SEO reality
Hosting helps SEO only when the basics stay stable
A VPS does not create rankings by itself. It helps when it gives you stable URLs, fast first responses, correct HTTPS redirects, clean metadata, matching JSON-LD, and fewer outages than the cheaper workaround you were using before.
HTTPS redirects
Redirect HTTP once, keep certificates renewing, and avoid mixed-content assets that make pages look broken.
Stable URLs
Use human-readable routes, keep canonical URLs consistent, and avoid deployment paths that change after every release.
VPS performance
Measure TTFB, cache static assets through Nginx, compress responses, and keep the first page load boringly fast.
SEO metadata
Keep title, H1, description, Open Graph image, Article schema, BreadcrumbList, and FAQPage schema aligned with visible content.
Automation option
Use GhostlyHosting when repeating the manual setup is the risky part
Manual setup is useful when you want to understand every moving part. If you already know the stack and want a guided repeatable deploy path, GhostlyHosting can automate the Ubuntu, Nginx, SSL, GitHub, and service-management workflow.
FAQ
Can I host Blazor Server on UpCloud for approx. $3/month?
Yes, for a modest app with careful expectations. The entry plan can handle a small launch, staging environment, or internal tool, but you still need monitoring, backups, patching, and a scale-up plan.
Do I need the full .NET SDK on the VPS?
Usually no. Install the ASP.NET Core runtime when you publish from your workstation or CI. Install the SDK only when the server intentionally builds or publishes the app.
Should Kestrel be exposed directly to the internet?
No. Bind Kestrel to localhost and expose Nginx on ports 80 and 443. Nginx handles TLS, redirects, proxy headers, and the public URL surface.
What are the biggest risks of cheap Blazor VPS hosting?
The common risks are unpatched packages, expired certificates, weak SSH hygiene, missing backups, disk pressure, noisy logs, and no one noticing when the service restarts repeatedly.
Does VPS hosting improve Blazor SEO?
Only when the setup improves fundamentals: stable HTTPS URLs, fast responses, clean metadata, matching JSON-LD, uptime, and predictable redirects. Hosting alone is not an SEO shortcut.
When should I use GhostlyHosting instead of doing this by hand?
Use manual setup to learn or audit the stack. Use GhostlyHosting when you want a repeatable Ubuntu, Nginx, SSL, GitHub, and service-management workflow after you understand the moving parts.