Mert Özen Further With Every Line

Blog

Mert Özen's blog posts on software development, backend, frontend, and DevOps.

Series
13 posts found #hosting
What Changed in Hosting from .NET 6 to .NET 10: Port 8080, HTTP_PORTS, KnownIPNetworks and More
DevOps PART 12

What Changed in Hosting from .NET 6 to .NET 10: Port 8080, HTTP_PORTS, KnownIPNetworks and More

Since .NET 8, ASP.NET Core images listen on 8080 instead of 80 and ship a ready-made app user, but the default user is still root; on .NET 10 the images are Ubuntu-based and KnownNetworks and WebHost are obsolete. With real runs we see the old -p 8000:80 command give a connection reset, why a non-root port 80 works on Docker but may not elsewhere, the traps in old tutorials and the .NET 11 breaking changes that touch hosting.

8 Nov 2026 9 min 4
Choosing Hosting and a Production Checklist: Nginx, IIS, Caddy, Containers and PaaS
DevOps PART 11

Choosing Hosting and a Production Checklist: Nginx, IIS, Caddy, Containers and PaaS

The hosting choice is decided first by what the team can operate, then by the number of services, deploy frequency and cost; a Linux VM with Nginx, IIS, Caddy, Traefik, YARP, PaaS and containers are different answers to the same questions. We try Caddy with seven lines of config and an active health check, and a ten-item pre-go-live check script catches a health endpoint invisible from outside and a missing default server on 443 in the seventh post's config.

8 Nov 2026 11 min 3
IIS in Production: Deploying, app_offline.htm, Locked Files, Application Initialization and Angular
DevOps PART 10

IIS in Production: Deploying, app_offline.htm, Locked Files, Application Initialization and Angular

The DLLs of an app running on IIS are locked; deploy with app_offline.htm or with enableShadowCopy, supported since .NET 7, and keep those settings in the project's web.config rather than on the server, since publish preserves them. Recycling and overlapped recycle, Application Initialization and idle timeout, Data Protection on IIS, sub-applications, Angular with URL Rewrite and AddWindowsService instead of IIS; IIS wasn't run on this Mac, the web.config and build outputs are real.

8 Nov 2026 11 min 4
ASP.NET Core on IIS: Hosting Bundle, ASP.NET Core Module, In-Process and Out-of-Process
DevOps PART 09

ASP.NET Core on IIS: Hosting Bundle, ASP.NET Core Module, In-Process and Out-of-Process

On IIS, ASP.NET Core is run by the ASP.NET Core Module; if the Hosting Bundle is installed before IIS it must be repaired, otherwise you get a 500.19 and not a single line of the app runs. We cover the web.config that publish produces, in-process versus out-of-process, app pool and ApplicationPoolIdentity permissions, and where errors such as 500.30, 500.31, 500.38 and 502.5 point you; IIS wasn't run on this Mac, the web.config outputs come from real publishes.

8 Nov 2026 9 min 3
Running a .NET App as a systemd Service on Linux
DevOps PART 08

Running a .NET App as a systemd Service on Linux

Run Kestrel under systemd as a separate user with Type=notify and AddSystemd, KillSignal=SIGTERM and hardening settings; KillSignal=SIGINT cuts open requests and systemd still reports success. We measure publish option sizes, the runtime coming from the distribution repository on Ubuntu 24.04, journald output, restart after a crash, the exposure score dropping from 9.2 to 3.8, and 0.2-second deploys and rollbacks with a releases/current symlink.

8 Nov 2026 12 min 4
HTTPS, Security Headers, Rate Limiting and Load Balancing in Nginx
DevOps PART 07

HTTPS, Security Headers, Rate Limiting and Load Balancing in Nginx

With real runs: TLS termination in Nginx, HTTP/3 with http2 on and listen quic, security headers that don't disappear thanks to add_header_inherit merge, HSTS from a single place, 429s with limit_req, and round robin spreading unevenly without an upstream zone. ip_hash, the sticky cookie that came with 1.29.6 and passive health checks with max_fails: when an instance dies the client sees no error, but non-idempotent requests and unhealthy yet running processes need separate handling.

8 Nov 2026 11 min 5
Serving Angular with Nginx: SPA Fallback, Cache Headers, Compression and an /api Proxy
DevOps PART 06

Serving Angular with Nginx: SPA Fallback, Cache Headers, Compression and an /api Proxy

Serving Angular with Nginx needs an SPA fallback with try_files, immutable caching for hashed bundles and no-cache for index.html; otherwise after a deploy a browser asking for an old chunk gets HTML with a 200. With real runs: gzip_static, a runtime config.json, a CORS-free setup with an /api proxy on the same origin, serving under a sub-path with base href, and the allowedHosts trap when putting Angular SSR on Node behind Nginx.

8 Nov 2026 11 min 4
Nginx as a Reverse Proxy for ASP.NET Core: proxy_pass, Headers, WebSockets/SignalR and Timeouts
DevOps PART 05

Nginx as a Reverse Proxy for ASP.NET Core: proxy_pass, Headers, WebSockets/SignalR and Timeouts

Since Nginx 1.29.7 upstream keepalive and HTTP/1.1 are the default, but only if you use an upstream block: proxy_pass to a direct address opens a new connection per request. We take Microsoft's reference config apart line by line and measure SignalR quietly falling back to long polling without the WebSocket upgrade map, buffering with SSE, aligning Nginx's and Kestrel's body and header limits, and telling 502 from 504 in the logs.

8 Nov 2026 11 min 5
Nginx Fundamentals: Installation, nginx.conf Structure, server and location Blocks
DevOps PART 04

Nginx Fundamentals: Installation, nginx.conf Structure, server and location Blocks

Installing Nginx from the nginx.org repository gives you the current stable branch (1.30); Ubuntu 24.04's package stays on 1.24. With real runs we look at master and worker processes, nginx.conf contexts, rejecting unknown hosts with default_server, the location matching algorithm (=, longest prefix, ^~, regex), root versus alias, the trailing slash in proxy_pass, and how reload and restart behave differently with a broken config.

8 Nov 2026 11 min 4
ASP.NET Core Behind a Reverse Proxy: Forwarded Headers, KnownIPNetworks and the Real Client IP
DevOps PART 03

ASP.NET Core Behind a Reverse Proxy: Forwarded Headers, KnownIPNetworks and the Real Client IP

An app behind a proxy sees the client's IP and HTTPS only if UseForwardedHeaders is set up correctly: you must say which headers to process and add the proxy's address to KnownProxies or, on .NET 10, KnownIPNetworks. With real runs we look at the HTTPS redirection loop, the ASPDEPR005 warning, fake X-Forwarded-For values and ForwardLimit, PathBase via X-Forwarded-Prefix and Data Protection keys across multiple instances.

8 Nov 2026 11 min 5
Getting to Know Kestrel: Endpoints, ASPNETCORE_HTTP_PORTS, Limits and HTTP/2–HTTP/3
DevOps PART 02

Getting to Know Kestrel: Endpoints, ASPNETCORE_HTTP_PORTS, Limits and HTTP/2–HTTP/3

Kestrel's listening address is decided by Listen in code, Kestrel:Endpoints, --urls/ASPNETCORE_URLS and ASPNETCORE_HTTP_PORTS, in that order, and every overridden setting shows up as a warning in the log. With nine runs we measure the precedence and look at PEM certificates and SNI, certificate renewal without a restart, default limits, HTTP/3 with libmsquic, connecting to Nginx over a Unix socket and the localhost trap in containers.

8 Nov 2026 14 min 4
Web Servers, Application Servers and Reverse Proxies: How Does an HTTP Request Reach Your App?
DevOps PART 01

Web Servers, Application Servers and Reverse Proxies: How Does an HTTP Request Reach Your App?

Kestrel is both a web server and an application server; a reverse proxy is the layer that accepts the request, forwards it to the app behind it and takes on TLS termination, static files, compression, buffering and load balancing. We send the same request straight to Kestrel and then through Nginx, compare the IP, headers and Angular deep-link behaviour the app sees, and put five hosting topologies side by side.

8 Nov 2026 10 min 4
Blog Map