MayWares

Notes on small software — building, deploying, and keeping it running.

Running the same site on two nginx server blocks

September 21, 2026 · 5 min read

I needed one document root exposed twice: plain HTTP on port 80 for the world, and TLS on a loopback-only listener for another local service to talk to. My first instinct was to duplicate the whole block. The actual answer is three lines — nginx server blocks are cheap, and root doesn't care how many servers point at it.

The config

server {
    listen 80;
    server_name blog.maywares.xyz;
    root /var/www/mysite;
    index index.html;
}

server {
    listen 127.0.0.1:8443 ssl;
    http2 on;
    server_name blog.maywares.xyz;

    ssl_certificate     /etc/ssl/private/blog.maywares.xyz.pem;
    ssl_certificate_key /etc/ssl/private/blog.maywares.xyz.key;
    ssl_protocols       TLSv1.2 TLSv1.3;

    root /var/www/mysite;
    index index.html;
}

Two listeners, one root, one server_name. Nothing shared by include file, nothing clever.

The pitfall

The one thing that bit me: on nginx ≥ 1.25, listen ... ssl http2; is deprecated in favor of the standalone http2 on; directive. The old form still works but logs a warning on every reload, and warnings you train yourself to ignore are how real problems hide. Split it out.

Also worth knowing: ssl_protocols in a server block overrides the http-level value for that server only, which is usually what you want — the loopback listener can be stricter than the public one, or vice versa, without one config leaking into the other.

Why not just proxy?

Because proxying to myself adds a hop, a config stanza, and a failure mode to serve bytes that are already on disk. If the consumer speaks TLS and lives on the same machine, a second server block is the smallest possible answer. Boring wins again.