# Server Blocks and Request Routing by Host — Nginx

Source: https://www.skillbyai.com/en/nginx/s-servers

> Configure virtual hosts with listen, server_name and default_server.

## Choosing which server handles a request

One NGINX instance can host many sites with **server blocks** (virtual hosts). For each request, NGINX first picks servers whose **`listen`** matches the address and port the connection arrived on, then compares the request's **Host** header with each **`server_name`**. Matching order: **exact names** first (`example.com`), then the longest **wildcard starting with an asterisk** (`*.example.com`), then the longest wildcard **ending** with one (`mail.*`), then the first matching **regular expression** (`~^(?<tenant>.+)\.app\.example\.com$`) in configuration order. If nothing matches, the **default server** for that listen socket handles the request: the one marked `default_server`, or else the first one defined. It is good practice to define an explicit default server that rejects unknown hosts (for example with `return 444;`, which closes the connection), so requests for random hostnames or bare IP addresses do not land on a real site.

## Picking a server block

The listen socket narrows the candidates; the Host header picks one; otherwise the default server answers.

![An incoming arrow reaching a sorting funnel, splitting into three site boxes with name tags and one grey box marked with a shield as the catch-all.](assets/figures/nginx/section-2-map.svg) — Figure 2.1 — Request routing by listen address and server_name.

## Several sites plus a catch-all

Unknown hosts never reach a real application.

```nginx
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
    return 444;                         # close connection for unknown hosts
}

server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/example;
}

server {
    listen 80;
    server_name ~^(?<tenant>[a-z0-9-]+)\.app\.example\.com$;
    root /var/www/tenants/$tenant;      # named capture used as a variable
}
```

## server_name _ is not magic

`_` is just an invalid hostname that never matches; what makes a block the catch-all is `default_server` on its listen directive (or being defined first). Be explicit.

**Quiz:** No server_name matches a request's Host header. Which server block handles it?

- [ ] NGINX returns 500
- [ ] The last server block in the file
- [x] The default server for that listen address and port
- [ ] A random server

*Answer:* The default server for that listen address and port. The default_server (or the first defined) for the matching listen socket handles unmatched hosts.
