BITCHLOVE/NET

Tough love, served neat. Now with a runtime.

.NET on Linux — no Windows in the building

This is net.bitchlove.com. ASP.NET Core 10 on Kestrel, reverse-proxied by nginx, supervised by systemd, on Ubuntu — using the runtime Ubuntu itself ships, not Microsoft's apt repo. Own runtime, own port, own unit, own certificate. Nothing borrowed from the estate, and nothing borrowed from IIS.

Every number on this page is read live from the running process on each request — procfs, cgroups, and glibc included. If it renders, the runtime is genuinely up. Not a status code pretending.

The stack, top to bottom

  1. Let's Encrypt TLS for net.bitchlove.com, auto-renewing via certbot's timer
  2. nginx terminates TLS on :443, redirects :80, proxies to loopback
  3. Kestrel 127.0.0.1:9050 — bound to loopback, unreachable from outside
  4. ASP.NET Core 10.0 Razor Pages, forwarded-headers aware
  5. systemd blnet.service, Type=notify, restart-always, capabilities dropped
  6. Ubuntu / Linux 7.0.0-29-generic the actual floor

Linux underneath

Distribution Ubuntu 26.04 LTS
Kernel 7.0.0-29-generic
C library glibc 2.43
Runtime identifierubuntu.26.04-x64
Framework root /usr/lib/dotnet/shared/Microsoft.NETCore.App/10.0.10
Runtime packaged byUbuntu archive (dotnet-sdk-10.0)
Running as blnet (uid 994)
Supervisor systemd
Cgroup /system.slice/blnet.service
Cgroup memory cap max (no MemoryMax= on the unit)
Load average 7.78 · 8.47 · 5.26
Time zone Etc/UTC

The C library line is a P/Invoke into gnu_get_libc_version — managed code calling straight into the glibc this process is already linked against. There is no managed API for it, which is rather the point: on Linux, .NET is a guest that can talk to the host directly.

The process itself

Runtime .NET 10.0.10
Operating systemUbuntu 26.04 LTS
Architecture X64
Machine bitchlove
Process ID 41295
OS threads 27
Logical CPUs 8
Garbage collectorserver, Interactive, heap limit 15.6 GiB
Managed heap 11.6 MB
Process uptime 0h 31m 11s
Server time 2026-08-08 12:36:11 UTC
Requests served 1

Requests served counts since the last restart, in-process. A drop back to 1 means the unit was restarted — by a deploy, or by Restart=always catching a crash.

Proxy chain

Client address 216.73.216.84
Scheme seen by apphttps

Forwarded headers are wired up, so the app sees the real caller and the original scheme rather than 127.0.0.1 over http. If scheme reads http in a browser, or client address reads ::ffff:127.0.0.1 from off-box, the nginx proxy_set_header block has drifted.

The bench