Lesson 2 of 6

Config Anatomy

Everything Nginx does is driven by one config language: directives (a name, some values, a semicolon) organized into nested blocks (a name and braces). Learn the shape once and every Nginx config on earth — including the gnarly ones — becomes readable.

💡 The Bottom Line

Config = directives inside contexts: http holds server blocks (one per site), which hold location blocks (one per URL pattern). Inner blocks inherit from outer ones. And the golden habit: nginx -t before every reload — test, then apply.

The shape, annotated

# /etc/nginx/nginx.conf (simplified)
worker_processes auto;            # directive: name value ;

http {                            # block: context for all web traffic
    include mime.types;

    server {                      # one website
        listen 80;
        server_name example.com;

        location / {              # one URL pattern within it
            root /var/www/example;
            index index.html;
        }

        location /api/ {          # another pattern, different handling
            proxy_pass http://localhost:3000;
        }
    }
}

Where files live, and the reload cycle

On Debian/Ubuntu, site configs live in /etc/nginx/sites-available/ (all your configs) with symlinks in /etc/nginx/sites-enabled/ (the active ones) — enabling a site is creating a symlink. Other distros use /etc/nginx/conf.d/*.conf. Either way, the change cycle is always:

sudo nano /etc/nginx/sites-available/mysite   # edit
sudo nginx -t                                  # TEST — syntax + sanity check
sudo systemctl reload nginx                    # apply with zero dropped connections

reload (not restart) tells workers to finish in-flight requests on the old config while new connections get the new one — config changes with zero downtime.

🙋 There Are No Dumb Questions

Q: What happens if I reload with a broken config?
A: If the syntax is invalid, the reload is refused and the old config keeps running — Nginx protects you there. The dangerous case is a config that's valid but wrong (proxying to the wrong port, wrong root path): that reloads fine and breaks your site. That's why nginx -t is necessary but not sufficient — test the actual behavior after reloading too.

⚠️ Watch Out

Every directive ends with a semicolon, and a missing one produces an error message pointing at the next line — unexpected "}" or unknown directive somewhere below the actual mistake. When nginx -t complains about a line that looks fine, check the line above it first.

🔧 Try It Yourself

Look at a real config right now. In the Docker container from Lesson 1:

docker exec -it nginx-lab sh
cat /etc/nginx/nginx.conf            # the main file — find the http block
cat /etc/nginx/conf.d/default.conf   # the server block serving the welcome page
nginx -t                             # run the test yourself
exit

Trace the request path: listen 80location /root /usr/share/nginx/html → the index.html you saw in your browser.

✅ Quick Check

What is the correct sequence for changing Nginx config on a live server?


Next up: putting the server block to work — serving a real static site, with root, try_files, and proper cache headers.

← Back to
Next →