Nginx

Nginx - Basic

Page 1 of 2

Why Nginx Exists

If you've deployed anything on the web, there's a good chance Nginx sat in front of it somewhere, quietly deciding which requests got through and where they went. It started life in 2004 when Igor Sysoev, a Russian engineer working on a large Russian web portal, got frustrated with how existing web servers like Apache handled traffic at real scale. Apache's classic model spins up a separate (or, in a later mode, a thread) for every single connection. That's simple to reason about, but it means memory and CPU scheduling overhead scale directly with your connection count. Get a few thousand slow clients (think mobile users on flaky connections, or long-lived API polling) and the server can grind to a halt just from bookkeeping, long before it runs out of actual work to do. This is famously known as the C10K problem, the challenge of handling ten thousand concurrent connections on one machine.

Nginx solves it with a completely different design: an event-driven architecture. Instead of one process per connection, a small, fixed number of worker processes each run a loop that waits for events (a new connection, data ready to read, a socket ready to write) and reacts to them, using operating system primitives like epoll on Linux to watch thousands of sockets at once without wasting a thread on each one. A single Nginx worker can comfortably juggle tens of thousands of idle or slow-moving connections because it isn't paying a per-connection process or thread tax. This is exactly why Nginx became the default choice for anything sitting on the edge of your infrastructure: serving static files, terminating client connections, and forwarding requests onward.

That "forwarding requests onward" part is worth naming early, because it's most of what you'll use Nginx for as a DevOps engineer. A web server just serves files directly off disk. A sits in front of one or more backend applications and forwards client requests to them, so the client never talks to your app server directly. A load balancer is a reverse proxy that spreads requests across multiple backend instances instead of just one. Nginx can be configured to do any of these, and very often does all three at once in the same config file.


Installing and Controlling Nginx

On most Linux distributions, Nginx is a package away:

# Debian / Ubuntu
sudo apt update && sudo apt install nginx

# RHEL / CentOS / Amazon Linux
sudo yum install nginx

Once installed, it's managed like any other system service:

sudo systemctl start nginx     # start it
sudo systemctl stop nginx      # stop it
sudo systemctl restart nginx   # stop, then start (brief downtime)
sudo systemctl enable nginx    # start automatically on boot
sudo systemctl status nginx    # is it running, and since when?

If you check running processes right after starting it, you'll see the architecture from the previous section made concrete:

opsquiz@devops-essentials
opsquiz@devops:~$ ps aux | grep nginx
root 1102 0.0 0.1 nginx: master process /usr/sbin/nginx
www-data 1103 0.0 0.2 nginx: worker process
www-data 1104 0.0 0.2 nginx: worker process

One master process, owned by root, and a handful of worker processes, usually running as an unprivileged user like www-data or nginx. The master process reads the config, binds to network ports (which requires root on ports below 1024, like 80 and 443), and manages the workers. It never actually handles a client request itself, the workers do all the real traffic handling. This split matters a lot once you get into config reloads later on, but for now, just know that "Nginx is running" really means "one master plus a few workers are running."


The Shape of nginx.conf

The main configuration file usually lives at /etc/nginx/nginx.conf. On Debian-based systems, it typically includes everything under /etc/nginx/sites-enabled/, which is usually a folder of symlinks pointing back into /etc/nginx/sites-available/. That two-folder pattern lets you keep a config written in sites-available without it being active, then "turn it on" just by symlinking it into sites-enabled.

Regardless of how the files are split up, the config is structured as nested blocks:

http {
    # settings that apply to all sites: mime types, gzip, logging defaults
    include mime.types;

    server {
        # one server block = one "virtual host", usually one domain
        listen 80;
        server_name example.com;

        location / {
            # matches request paths and decides what to do with them
            root /var/www/example;
        }
    }
}

Read that from the outside in: http is the outermost block for anything web-related, server defines one site (Nginx can run many server blocks side by side, routed by server_name and the Host header the client sends), and location matches specific URL paths within that site and decides what happens to them, serve a file, proxy to a backend, redirect, and so on. Nearly everything you write in Nginx lives inside this httpserverlocation nesting.


    Welcome to OpsQuiz!

    Real scenario-based DevOps questions, hands-on practice, and clear explanations for every answer.