| |

LFCS 157 ๐Ÿง Web Server โ€” Nginx Basics

โฑ๏ธ Estimated read: 10 min | |

The previous chapters covered the virtualization and containerization of the application environments. This chapter introduces the web server that often sits in front of those environments: Nginx. The LFCS exam lists “Configure an HTTP server” and “Restrict access to a web page” under the Service Configuration domain . Nginx is a high-performance, event-driven web server and reverse proxy. Unlike Apache, which spawns a process or thread per connection, Nginx uses a master-worker architecture. A single master process manages the configuration and the worker processes, while the workers handle the actual requests using an event-based model that efficiently distributes the load . The critical trap is the configuration reload: editing the nginx.conf file does nothing until the nginx -s reload command is executed, and the reload must be preceded by the nginx -t syntax check to prevent the configuration error from taking the server down.

Key point: The master process reads the configuration and manages the workers. The workers handle the requests. The configuration file is /etc/nginx/nginx.conf. The nginx -t command validates the syntax. The nginx -s reload command applies the change gracefully, without dropping the active connections. The systemctl reload nginx command is the systemd equivalent.


Why Nginx basics require a specific mental model

The master-worker problem. Nginx is not a single process. The nginx executable starts the master process, which reads the configuration and binds to the ports. The master then spawns the worker processes, which do the actual request handling. The number of workers is set by the worker_processes directive, often auto to match the CPU cores. The master does not handle the requests; it only manages the workers . The ps -ax | grep nginx command shows both the master and the workers. The kill -s QUIT <master_pid> command gracefully stops the workers and the master.

The reload problem. The nginx -s reload command sends the HUP signal to the master. The master reads the new configuration, validates the syntax, and if it is valid, starts the new workers with the new configuration and tells the old workers to finish their current requests and exit. If the syntax is invalid, the master rolls back and continues with the old configuration . The nginx -t command performs the same syntax check without applying the change. The reload is graceful; the restart is not. The systemctl restart nginx kills the workers, drops the connections, and starts the new processes.

The configuration context problem. The nginx.conf file uses a nested block structure. The events and http blocks are in the main context. The server block is inside http. The location block is inside server . Each block is a context. The directives in the http block apply to all servers. The directives in the server block apply to that specific virtual host. The directives in the location block apply to the matching URI. The nesting is the configuration hierarchy.

The static content problem. The root directive sets the directory that the server uses to serve the static files. The location / block with the root /var/www/html serves the index.html from that directory. The index directive specifies the default file name. The try_files directive is the fallback for the single-page applications . The static content is the simplest use case and the foundation for the reverse proxy.

The virtual host problem. A single Nginx instance can serve multiple domains. Each domain has its own server block with the server_name directive. The listen directive sets the port. The server block that matches the Host header is the one that handles the request. The default server is the first server block for the port, or the one marked with default_server . The virtual hosts are the mechanism for the multi-site hosting.

The trade-off. The Nginx configuration is more complex than the Apache .htaccess approach, but it is also more explicit and more performant. The nginx -t and nginx -s reload workflow is the discipline that prevents the configuration errors from becoming the outages. The exam tests the commands and the configuration structure.


a. The installation and the service management

The installation is the package manager. The service management is systemd.

# Install on Debian/Ubuntu
sudo apt install nginx

# Install on RHEL/Fedora
sudo dnf install nginx

# Start the service
sudo systemctl start nginx

# Enable on boot
sudo systemctl enable nginx

# Check the status
sudo systemctl status nginx

# Test the configuration syntax
sudo nginx -t

# Reload the configuration gracefully
sudo systemctl reload nginx

# Or with the nginx signal
sudo nginx -s reload

The nginx -t output shows the configuration file path and the syntax status. The syntax is ok and test is successful lines are the confirmation. The systemctl reload sends the HUP signal to the master, which performs the graceful reload .

The nginx -s stop command is the fast shutdown. The nginx -s quit is the graceful shutdown. The systemctl stop nginx is the service manager’s stop .


b. The configuration structure and the static site

The nginx.conf file has the main context, the events block, and the http block. The server block is inside http.

# /etc/nginx/nginx.conf (simplified)
user www-data;
worker_processes auto;
pid /run/nginx.pid;

events {
    worker_connections 768;
}

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

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

        location / {
            try_files $uri $uri/ =404;
        }
    }
}

The worker_processes auto matches the CPU cores. The events block sets the connection limit per worker. The http block includes the MIME types and sets the defaults. The server block listens on port 80 for example.com. The root sets the document root. The location / block uses try_files to serve the file or return the 404 .

The include directive is the mechanism for the modular configuration. The Debian/Ubuntu packages use the sites-available and sites-enabled directories. The sites-enabled contains the symlinks to the active configurations in sites-available. The nginx.conf includes the sites-enabled/* . The RHEL/Fedora packages use the conf.d/*.conf directory.


c. The reverse proxy and the access restriction

The reverse proxy forwards the requests to the backend application. The proxy_pass directive sets the backend URL.

server {
    listen 80;
    server_name app.example.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

The proxy_pass http://127.0.0.1:3000 forwards the request to the application on the local port 3000. The proxy_set_header directives pass the original host, the client IP, and the protocol to the backend . The backend sees the original request information, not the Nginx IP.

The access restriction uses the allow and deny directives.

location /admin {
    allow 192.168.1.0/24;
    deny all;
    proxy_pass http://127.0.0.1:3000;
}

The allow 192.168.1.0/24 permits the local subnet. The deny all blocks the other addresses. The order matters: the first matching rule wins. The /admin location is restricted to the internal network .


Complete Example Session

# ============================================
# PART 1: INSTALL AND START
# ============================================

sudo apt install nginx
sudo systemctl start nginx
sudo systemctl enable nginx
# ============================================
# PART 2: TEST THE DEFAULT PAGE
# ============================================

curl http://localhost
# The default Nginx welcome page.
# ============================================
# PART 3: CHECK THE CONFIGURATION
# ============================================

sudo nginx -t
# nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
# nginx: configuration file /etc/nginx/nginx.conf test is successful
# ============================================
# PART 4: CREATE A STATIC SITE
# ============================================

sudo mkdir -p /var/www/mysite
echo "<h1>My Site</h1>" | sudo tee /var/www/mysite/index.html
# ============================================
# PART 5: ADD A SERVER BLOCK
# ============================================

sudo tee /etc/nginx/sites-available/mysite <<'EOF'
server {
    listen 80;
    server_name mysite.local;
    root /var/www/mysite;
    index index.html;
    location / { try_files $uri $uri/ =404; }
}
EOF

sudo ln -s /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled/
# ============================================
# PART 6: TEST AND RELOAD
# ============================================

sudo nginx -t
sudo systemctl reload nginx
# ============================================
# PART 7: VERIFY THE SITE
# ============================================

curl -H "Host: mysite.local" http://localhost
# <h1>My Site</h1>
# ============================================
# PART 8: ADD A REVERSE PROXY
# ============================================

sudo tee /etc/nginx/sites-available/api <<'EOF'
server {
    listen 80;
    server_name api.local;
    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
EOF

sudo ln -s /etc/nginx/sites-available/api /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
# ============================================
# PART 9: RESTRICT ACCESS
# ============================================

sudo tee /etc/nginx/sites-available/admin <<'EOF'
server {
    listen 80;
    server_name admin.local;
    location / {
        allow 192.168.1.0/24;
        deny all;
        proxy_pass http://127.0.0.1:3000;
    }
}
EOF

sudo ln -s /etc/nginx/sites-available/admin /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

The nine parts trace the Nginx basics: install, verify, test config, static site, server block, reload, verify site, reverse proxy, and access restriction.


Quick Reference

Service Commands

CommandPurpose
systemctl start nginxStart
systemctl stop nginxStop
systemctl reload nginxGraceful reload
systemctl restart nginxFull restart
nginx -tTest config
nginx -s reloadReload via signal

Configuration Contexts

ContextLocation
mainOutside blocks
eventsInside main
httpInside main
serverInside http
locationInside server

Static Site Directives

DirectivePurpose
listenPort
server_nameDomain
rootDocument root
indexDefault file
try_filesFallback

Reverse Proxy

DirectivePurpose
proxy_passBackend URL
proxy_set_headerPass headers
allowPermit IP
denyBlock IP

Best Practices

โœ… Do This:

sudo nginx -t
<!-- Test the config before reload -->                # โœ…
sudo systemctl reload nginx
<!-- Reload gracefully -->                            # โœ…
proxy_set_header Host $host;
<!-- Pass the original host to the backend -->        # โœ…

โŒ Don’t Do This:

sudo systemctl restart nginx
# For the configuration change
<!-- Use reload to avoid the connection drop -->      # โŒ
# Edit the config and assume it is active
<!-- The reload is required -->                      # โŒ
# Put the server block in the main context
<!-- The server block belongs in http -->            # โŒ

Common Pitfalls

PitfallWhy It HappensFix
Config not appliedNo reloadsystemctl reload nginx
Syntax error crashes serverNo nginx -tTest before reload
403 ForbiddenWrong root or permissionsCheck the directory
Backend not reachableWrong proxy_passCheck the backend URL
Site not matchingWrong server_nameCheck the Host header

Real-World Examples

1. Install Nginx

sudo apt install nginx

2. Test Config

sudo nginx -t

3. Reload

sudo systemctl reload nginx

4. Static Site

server { listen 80; root /var/www/html; }

5. Reverse Proxy

location / { proxy_pass http://127.0.0.1:3000; }

6. Pass Headers

proxy_set_header Host $host;

7. Allow Subnet

allow 192.168.1.0/24;

8. Deny All

deny all;

9. Server Name

server_name example.com;

10. Graceful Stop

sudo nginx -s quit

Visual

Master-Worker Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Master Process                              โ”‚
โ”‚  โ”œโ”€โ”€ Reads config                            โ”‚
โ”‚  โ”œโ”€โ”€ Binds ports                             โ”‚
โ”‚  โ””โ”€โ”€ Manages workers                         โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Worker Processes                            โ”‚
โ”‚  โ”œโ”€โ”€ Handle requests                         โ”‚
โ”‚  โ”œโ”€โ”€ Event-driven                            โ”‚
โ”‚  โ””โ”€โ”€ Distribute load                         โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Reload Flow

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  nginx -s reload                             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Master validates new config                 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
           โ”‚ VALID                 โ”‚ INVALID
           โ–ผ                       โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  New workers start   โ”‚  โ”‚  Rollback to old     โ”‚
โ”‚  Old workers finish  โ”‚  โ”‚  config              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Summary

ItemValue
Configuration file/etc/nginx/nginx.conf
Test syntaxnginx -t
Reloadsystemctl reload nginx
Static rootroot /var/www/html
Reverse proxyproxy_pass http://...
Access allowallow <ip>
Access denydeny all
Master processManages workers
Worker processHandles requests

Key takeaways:

  • Nginx uses a master-worker model. The master process reads the configuration and manages the workers. The workers handle the requests using the event-driven model. The ps -ax | grep nginx shows both .
  • The configuration must be tested and reloaded. The nginx -t validates the syntax. The systemctl reload nginx applies the change gracefully. The restart drops the connections and is not the correct command for the configuration change .
  • The context nesting is the configuration structure. The server block is inside the http block. The location block is inside the server block. The directives apply to their context and the nested contexts .
  • The static site uses the root and the try_files. The root sets the document directory. The try_files is the fallback for the missing files. The index is the default file name.
  • The reverse proxy forwards the request with the headers. The proxy_pass sets the backend. The proxy_set_header passes the original host, the client IP, and the protocol. The access restriction uses the allow and deny .

Remember: The master is the manager. The worker is the handler. The nginx -t is the check. The reload is the apply. The restart is the kill. The server is the virtual host. The location is the URI match. The proxy_pass is the forward. The exam tests the commands and the configuration structure.

Was this helpful?


Stop using slow, ad-bloated tool sites! ๐Ÿคฎ

๐Ÿ”Ž Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
โœ… Finance (Mortgage, Interest, Inflation)
โœ… Tech (Base64, JSON, Dev Suite, IP)
โœ… Health (BMI, BMR, TDEE)
โœ… Productivity (Timer, Workspace, QR)

โšก๏ธ Fast & Private
๐Ÿ”’ No data leaves your device
๐Ÿ’Ž 100% Free

๐Ÿ”— Use it now: https://tools.kandz.me
๐Ÿ”– Bookmark itโ€”youโ€™ll need it later!