bundlewrap/bundles/nginx
CroneKorkN 6f2073847d
nginx/README: how port 80 is served + vm/cores requirement
Two things from the left4me-integration session worth pinning:

- 80.conf was orphaned in sites/ (not sites-enabled/) for an
  unknown amount of time. Commit d49259f moved it; document the
  resulting wiring so it's not re-broken accidentally.
- items.py reads node.metadata.get('vm/cores') with no default
  for worker_processes; bare-metal nodes outside the vm group
  raise at item-build time. Cost the agent ~10 min when
  ovh.left4me first opted into webserver.

Also note the cross-namespace read on letsencrypt/domains.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 20:47:47 +02:00
..
files nginx use expected dirs and allow websockets in proxy pass 2025-06-22 09:49:27 +02:00
items.py nginx: move 80.conf to sites-available so it's actually included 2026-05-10 19:59:17 +02:00
metadata.py yurlls fix monitoring and use dehydrated certs 2025-06-29 14:46:39 +02:00
README.md nginx/README: how port 80 is served + vm/cores requirement 2026-05-10 20:47:47 +02:00

nginx

Webserver. Per-node vhosts in nginx/vhosts; per-vhost templates in data/nginx/*.conf.

How port 80 is served

The bundle ships a fixed 80.conf to /etc/nginx/sites-available/80.conf (picked up by the sites-enabled/ symlink) that handles all port-80 traffic across vhosts:

  1. ACME HTTP-01 challenges (/.well-known/acme-challenge/) are served from /var/lib/dehydrated/acme-challenges/.
  2. All other port-80 requests are 301-redirected to https://$host$request_uri.

Per-vhost templates only declare listen 443 ssl http2;, so they don't need their own port-80 server blocks. If you need vhost- specific port-80 behaviour (e.g. plain-HTTP without redirect), override 80.conf or add a per-vhost block.

Required metadata

  • vm/cores — read directly by items.py for worker_processes. No default; bw items <node> raises at item-build time if missing. Typically supplied by the vm bundle / hetzner-vm group; double- check on bare-metal hosts.
  • nginx/vhosts — dict of vhost-name → vhost-config.
  • nginx/modules — list of dynamic modules to load.

Cross-namespace

items.py reads letsencrypt/domains to skip emitting a per-vhost HTTPS block when LE hasn't declared the domain yet — keeps the bundle loadable on a node where letsencrypt isn't fully wired up.