Installing nginx and understanding the configuration layout

Package and source installs, the main, events and http contexts, conf.d versus sites-available, include order, and testing and reloading safely.

Installing and finding the files

# Debian and Ubuntu: the official repo has a newer build than the distribution
sudo apt install nginx
nginx -v                       # the version
nginx -V                       # version plus every compile-time module and prefix

# RHEL family
sudo dnf install nginx

# inspect what the running binary actually loads
nginx -V 2>&1 | tr ' ' '\n' | grep -E 'prefix|conf-path|modules-path'
Path (Debian layout)PurposeEdited by
/etc/nginx/nginx.confThe root config, includes the restYou, rarely
/etc/nginx/conf.d/*.confIncluded one level downPackages often drop files here
/etc/nginx/sites-availableAll your site configsYou
/etc/nginx/sites-enabledSymlinks to active sitesYou, via ln -s
/var/log/nginxAccess and error logsnginx

The sites-available and sites-enabled convention is a Debian and Ubuntu packaging choice, not an nginx feature. On other distributions you will find a single conf.d directory instead.

The three contexts that matter

# main context: global settings, no braces around a directive
user  www-data;
worker_processes  auto;
pid  /run/nginx.pid;

events {
    worker_connections  1024;
    multi_accept  on;
}

http {
    include  /etc/nginx/mime.types;
    default_type  application/octet-stream;
    sendfile  on;
    keepalive_timeout  65;

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;

    server {
        listen  80;
        server_name  example.com;
        root  /var/www/example;
    }
}
  • Directives inherit downwards: a value set in http applies to every server and location unless overridden.
  • include is resolved relative to the prefix, usually /etc/nginx, not to the file that contains it.
  • Glob includes are expanded in alphabetical order, so 00-default.conf is read before 10-app.conf.
  • An events block is required exactly once, and not every directive is valid in every context — the error message names the allowed contexts.

Testing and reloading safely

sudo nginx -t                       # parse and test the whole config
sudo nginx -t -c /etc/nginx/nginx.conf
sudo nginx -T                       # dump the fully expanded config with includes

sudo systemctl reload nginx         # graceful: old workers finish, new ones start
sudo nginx -s reload                # the same via a signal
sudo nginx -s quit                  # graceful shutdown

# never do this on a busy server
sudo systemctl restart nginx
⚠️
A reload only succeeds if the new config parses and all new files exist. Bind mounts that are not yet in place, or a certificate path with a typo, fail the reload and leave the old workers running — check the error log rather than assuming the change took effect.

FAQ

What is the difference between reload and restart?
A reload starts new worker processes with the new config and lets the old ones finish in-flight requests, with no dropped connections. A restart stops everything first, which means errors for whoever is connected.
Which config file should I actually edit?
Add your own file in sites-available and symlink it into sites-enabled. Editing nginx.conf directly makes upgrades and package updates harder to reason about.

How nginx matches a request: locations and rewrite phases Logging, metrics and debugging a config

Last refreshed 2026-09-18.