server {
  listen [::]:80;
  listen 80;
  server_name laminar.example.com;

  # rule for letsencrypt ACME challenge requests
  location ^~ /.well-known/acme-challenge/ {
    default_type "text/plain";
    alias /srv/www/acme-challenge/;
  }

  # redirect all other http to https
  return 301 https://$server_name$request_uri;
}

server {
  # http2 is recommended because browsers will only open a small number of concurrent SSE streams over http1
  listen [::]:443 ssl http2;
  listen 443 ssl http2;
  server_name laminar.example.com;

  # modern tls only, see https://syslink.pl/cipherlist/ for a more complete example
  ssl_protocols TLSv1.3;
  ssl_ciphers EECDH+AESGCM:EDH+AESGCM;

  # set according to ACME/letsencrypt client
  ssl_certificate /path/to/certificate.crt;
  ssl_certificate_key /path/to/private.key;

  # use "location /" if laminar is to be accessible at the (sub)domain root.
  # alteratively, use a subdirectory such as "location /my-laminar/" and ensure that
  # LAMINAR_BASE_URL=/my-laminar/ accordingly.
  location / {
    # set proxy_pass according to LAMINAR_BIND_HTTP.
    # note that the laminar default for LAMINAR_BIND_HTTP is *:8080, which binds on all interfaces
    # instead of just the loopback device and is almost certainly not what you want if you are using
    # a reverse proxy. It should be set to 127.0.0.1:8080 at a minimum, or use unix sockets for more
    # fine-grained control of permissions.
    # see http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
    # and https://laminar.ohwg.net/docs.html#Running-on-a-different-HTTP-port-or-Unix-socket
    proxy_pass http://127.0.0.1:8080/;

    # required to allow laminar's SSE stream to pass correctly
    proxy_http_version 1.1;
    proxy_set_header Connection "";
  }

  # have nginx serve artefacts directly rather than having laminard do it
  location /archive/ {
    alias /var/lib/laminar/archive/;
  }
}