Once DNS has done its job, the browser knows the server’s IP address. It may seem that everything after that is simple: the request reached the machine, so the machine shows the site. But one server can host several sites, APIs, control panels and other services at the same time. Sometimes they all use the same IP address.
So how does the server know which site the visitor actually wants? Very often, the answer is Nginx. It accepts the incoming request, looks at where it arrived and which domain it is meant for, chooses the matching configuration and decides what to do next: return a ready file, redirect the visitor, or pass the request to another application.

The request has already reached the server
In the previous article we stopped around the chain domain → DNS → IP address. The browser now knows which machine it needs to contact.
A new part of the route begins:
The IP alone still does not tell the server which page to show. It identifies only the machine, and that machine may host the main site, a subdomain, a shop, an API and an admin panel.
First comes the port
When a browser connects to a server, it connects not only to an IP address but to a specific port. For the web, two ports are used most often: 80 for HTTP and 443 for HTTPS.
You can imagine a server as a large building with many doors. The IP address brings us to the building. The port determines the door.
203.0.113.10:80
203.0.113.10:443These numbers are rarely visible in a normal browser address bar because HTTP and HTTPS have standard defaults. When we enter https://example.com, the browser normally assumes port 443.
What listen means
One of the simplest Nginx server blocks can look like this:
server {
listen 80;
}This says: accept HTTP requests that arrive on port 80. HTTPS commonly uses listen 443 ssl;.
But a port is not enough. If several sites live on port 80 or 443, Nginx still has to understand which one the user wants. That is where server_name appears.
server_name — the site name this block expects
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example;
index index.html;
}listen 80 says where to accept requests. server_name says which domain names this configuration is for. root shows where the site files live. index says which file should be treated as the directory’s main page.
How Nginx knows the domain
DNS has already turned the domain name into an IP, but the name does not disappear. When the browser sends an HTTP request, it tells the server which site it wants. In simplified form:
GET / HTTP/1.1
Host: example.comNginx sees Host: example.com and compares that name with its server_name values. If it finds a matching block, it uses it. That is why one IP can easily serve many domains.
One server, one IP, many sites
Imagine two sites on one machine:
server {
listen 80;
server_name cats.example;
root /var/www/cats;
}
server {
listen 80;
server_name dogs.example;
root /var/www/dogs;
}Both sites may have the same IP. But the browser sends the site name. For cats.example, Nginx chooses the first block; for dogs.example, the second.
What root means
Once Nginx has chosen the right site, it has to know where its files are. The root directive is often used for this.
root /var/www/example;If the browser asks for https://example.com/about.html, a simple configuration may make Nginx look for /var/www/example/about.html. For /images/cat.jpg, it looks in /var/www/example/images/cat.jpg.
Why index.html opens
When a user enters only https://example.com/, no specific file is named. The server still has to show something.
index index.html;If a directory is requested, Nginx tries to find index.html inside it. This is one of the web’s oldest conventions: a site’s home page often lives in that file.
What if the file is missing?
If the browser asks for /photo.jpg and the file does not exist, Nginx cannot invent it. In a simple setup, the server responds with 404 Not Found.
But Nginx can behave more flexibly: show a custom error page, redirect the request, pass it to an application, or serve several URLs with one handler.
Nginx may not store the site at all
Not every site consists of ready-made HTML files. A modern application may run on Node.js, Python, Go, PHP or another platform. For example, the application may listen on the internal address 127.0.0.1:3000.
location / {
proxy_pass http://127.0.0.1:3000;
}The chain becomes:
The application creates the response, Nginx receives it and returns it to the browser. This mode is called a reverse proxy. The name sounds much scarier than the principle itself.
Why put Nginx in front of an application?
An application can sometimes accept external requests directly. But a separate web server provides a useful division of responsibilities.
Why location exists
Requests inside one site can be divided too. Images can come from disk while the API is passed to an application.
location /images/ {
root /var/www/example;
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
}Nginx gradually narrows the route: which port the request reached → which domain it is for → which path it has → what should be done with it.
Why ports 80 and 443 exist together
For most modern sites, the final destination is HTTPS. But port 80 often remains open: it accepts an ordinary HTTP request and sends the user to the secure version.
server {
listen 80;
server_name example.com;
return 301 https://example.com$request_uri;
}The browser receives the new address and makes the next request through port 443.
What happens on port 443?
HTTPS adds another layer. Before the normal HTTP request, a secure connection must be established and the server must present a certificate for the right domain.
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /path/to/certificate.pem;
ssl_certificate_key /path/to/private-key.pem;
root /var/www/example;
}That is why “DNS works, but the site shows a certificate error” is a perfectly normal diagnostic state. DNS has already completed its part. The error appeared at the next layer.
How HTTPS chooses the site before the HTTP request
HTTPS has an interesting detail: the certificate must be chosen and the secure channel established before the Host header appears inside the HTTP request. Modern browsers therefore send the desired site name during the TLS connection itself. The mechanism is called SNI — Server Name Indication.
In simplified terms, the browser says: “I am connecting to this IP, but I want example.com.” Nginx receives the name early enough to choose the appropriate HTTPS configuration and certificate.
What if there is no matching server_name?
If Nginx cannot find a matching configuration, it still has to choose some server block. Usually it uses the default configuration for that address and port.
listen 80 default_server;That is why opening an IP directly may show another site, an Nginx placeholder or an error. It does not necessarily mean something is broken: the site may be configured only for a specific domain.
Why the wrong site can still open after DNS is configured
Imagine that DNS already returns the new IP, the request definitely reaches the right server, but the user sees another project or the standard Nginx page. The problem is now almost certainly not DNS.
Check server_name, whether the required configuration is active, the port, root, and whether another default_server is intercepting the request.
Do not start fixing DNS again
If the domain already reaches the correct server but an Nginx page appears instead of the site, the previous layer works. Move forward through the chain instead of going backward.
How to test configuration before applying it
Nginx has a useful habit: configuration can be checked before it is applied.
nginx -tIf the test succeeds, the configuration can be reloaded:
systemctl reload nginxreload asks the running Nginx process to adopt the new configuration. For ordinary site changes, this is often better than a full restart.
Where the configuration usually lives
Exact paths depend on the system and installation method. On Linux, the main file is often /etc/nginx/nginx.conf, while site configurations live in /etc/nginx/sites-available/, /etc/nginx/sites-enabled/ or /etc/nginx/conf.d/.
The important thing is not memorizing a directory but understanding the structure: there is a main configuration, it includes additional files, and those files contain individual server blocks.
Why a configuration file can exist but still do nothing
A file can sit on the server, look perfect and still not participate in operation at all. For example, it may be in the directory of available configurations but not linked into the active set.
So “does the file exist?” is not the same question as “is Nginx actually reading it?” Diagnostics should check the active configuration.
A redirect is not moving a file
When Nginx executes return 301, it does not fetch a page from another address and relay it itself. It tells the browser: “go to this other address.” The browser receives a new URL and makes a new request.
This is fundamentally different from proxying.
Several services on one machine
Now we can build a diagram like the cover. The main site, API and shop live on one server. DNS for all three names points to one IP, while Nginx separates the requests.
For the user these are three different services. For Nginx they are three routing rules. That is one of its core jobs.
Nginx does not know what you “meant”
The server works literally. If DNS contains one domain while server_name contains another, it will not guess that they are almost the same. If an application runs on port 3000 while proxy_pass points to 3001, that is where the request will go.
This strictness can be annoying during setup, but it is exactly what makes server behavior predictable. The computer is not being difficult — it is very consistently doing not what you wanted, but what you wrote.
Good diagnostics follow the chain
When a site does not open, it is more useful to follow the full request path than to change settings at random.
Every successfully checked stage rules out an entire class of problems. If DNS returns the right IP, move on. If TLS connects, do not go back to DNS. If Nginx chose the correct block, check the file or application.
What a complete ordinary site looks like
server {
listen 80;
server_name example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /path/to/certificate.pem;
ssl_certificate_key /path/to/private-key.pem;
root /var/www/example;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}The first part accepts HTTP and redirects it to HTTPS. The second accepts the secure connection. server_name defines the domain, the certificate handles TLS, root points to the site directory, and location defines how a path is processed.
Nginx is good precisely because it is boring
At first, Nginx can look like a collection of obscure directives. At heart, however, it performs mechanical work: accept a connection, identify the site, inspect the path, apply a rule, return a response.
That is a good thing. Infrastructure is especially pleasant when it is predictable. The fewer surprises between a user’s request and the site’s page, the better.