Chuyển đến nội dung chính

Lesson 1: Introduction to Nginx and Installation

An introductory lesson on Nginx with its event-driven architecture, installation guide for Ubuntu/CentOS/macOS/Windows, directory structure, and basic management commands such as start, stop, and reload. You will understand the difference between Nginx and Apache and troubleshoot common issues.

🔒 DevSecOps — Lesson 1 Lesson 1: Introduction to Nginx and Installation

Nginx from Basics to Advanced

Part 1: Basics

xdev.asia

1. What is Nginx?

Nginx (pronounced "engine-x") is a powerful, high-performance open-source web server developed by Igor Sysoev in 2004. Originally created to solve the C10K problem (handling 10,000 concurrent connections), Nginx has quickly become one of the most popular web servers in the world.

Nginx is not just a web server — it can also function as:

  • Reverse proxy server
  • Load balancer
  • HTTP cache
  • Mail proxy server
  • API Gateway

Event-driven and Non-blocking I/O Architecture

Nginx's greatest strength lies in its architecture. Unlike the traditional model, Nginx uses an event-driven and non-blocking I/O (asynchronous) architecture.

How it works:

  1. Master Process: A single master process reads and evaluates the configuration, and manages worker processes
  2. Worker Processes: Multiple worker processes handle the actual connections
  3. Event Loop: Each worker process uses an event loop to handle thousands of connections simultaneously

Non-blocking I/O means:

  • When a worker process is waiting for I/O (file reads, database queries, network requests), it is not "blocked" — it can handle other requests in the meantime
  • A single worker process can handle thousands of connections simultaneously
  • Significant savings in CPU and RAM resources

Illustrative example:

Apache (Blocking):
Request 1 → Thread 1 → Wait for file read (blocked) → Complete
Request 2 → Thread 2 → Wait for file read (blocked) → Complete
Request 3 → Thread 3 → Wait for file read (blocked) → Complete
→ 3 threads needed for 3 requests

Nginx (Non-blocking): Request 1 → Worker → Wait for I/O → Handle Request 2 → Handle Request 3 → Request 1 done Request 2 → Same Worker Request 3 → Same Worker → Only 1 worker needed for 3 requests


2. Nginx vs Apache Comparison

Criterion Nginx Apache
Architecture Event-driven, asynchronous Process/Thread-based
Connection handling One worker handles many connections One thread/process per connection
Memory Very low, stable Grows with connection count
Static content Extremely fast Fast but slower than Nginx
Dynamic content Requires backend integration (PHP-FPM) Can handle directly (mod_php)
Configuration Centralized, file-based Distributed (.htaccess)
Modules Must be compiled in advance Dynamic module loading
Rewrite rules Different, simpler Powerful via .htaccess
Best suited for High traffic, static content, reverse proxy Shared hosting, dynamic content processing

When to use Nginx:

  • Serving static files (HTML, CSS, JS, images)
  • Reverse proxy for application servers
  • Load balancing
  • High concurrency (many simultaneous connections)
  • High performance with limited resources

When to use Apache:

  • Shared hosting environments
  • Need .htaccess flexibility
  • Many dynamic modules
  • Legacy applications dependent on Apache-specific features

Current trend: Many systems use a combination: Nginx as the front-facing reverse proxy, Apache handling dynamic content behind it.


3. Installing Nginx

3.1. Install on Ubuntu/Debian

Method 1: Install from default repository (simplest)

# Update package list
sudo apt update

Install Nginx

sudo apt install nginx -y

Check version

nginx -v

Check status

sudo systemctl status nginx

Method 2: Install from official Nginx repository (latest version)

# Install prerequisites
sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring

Import official nginx signing key

curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor
| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null

Setup repository

echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg]
http://nginx.org/packages/ubuntu lsb_release -cs nginx"
| sudo tee /etc/apt/sources.list.d/nginx.list

Update and install

sudo apt update sudo apt install nginx -y

3.2. Install on CentOS/RHEL

Method 1: From EPEL repository

# CentOS 7
sudo yum install epel-release -y
sudo yum install nginx -y

CentOS 8 / Rocky Linux / AlmaLinux

sudo dnf install nginx -y

Start and enable

sudo systemctl start nginx sudo systemctl enable nginx

Open firewall

sudo firewall-cmd --permanent --add-service=http sudo firewall-cmd --permanent --add-service=https sudo firewall-cmd --reload

Method 2: From official Nginx repository

# Create repo file
sudo tee /etc/yum.repos.d/nginx.repo <<EOF
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/\$releasever/\$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
EOF

Install

sudo yum install nginx -y

3.3. Install on macOS

Using Homebrew:

# Install Homebrew (if not already installed)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Install Nginx

brew install nginx

Start Nginx

brew services start nginx

Or run in foreground

nginx

Check

nginx -v

Paths on macOS:

  • Config: /usr/local/etc/nginx/nginx.conf
  • Document root: /usr/local/var/www
  • Logs: /usr/local/var/log/nginx

3.4. Install on Windows

Step 1: Download

Step 2: Extract and run

# Extract to C:\nginx

Open Command Prompt as Administrator

cd C:\nginx

Start Nginx

start nginx

Or

nginx.exe

Managing Nginx on Windows:

# Check version
nginx -v

Test configuration

nginx -t

Stop

nginx -s stop

Reload

nginx -s reload

Quit gracefully

nginx -s quit

Note: On Windows, Nginx is less stable than on Linux and should not be used in production.


4. Directory Structure and Basic Configuration Files

4.1. Directory structure on Ubuntu/Debian

/etc/nginx/
├── nginx.conf                 # Main configuration file
├── mime.types                 # MIME type definitions
├── fastcgi_params            # FastCGI parameters
├── proxy_params              # Proxy parameters
├── sites-available/          # Available site configurations
│   └── default              # Default virtual host
├── sites-enabled/            # Symlinks to active sites
│   └── default -> ../sites-available/default
├── conf.d/                   # Additional configurations
├── modules-available/        # Available modules
└── modules-enabled/          # Enabled modules

/var/log/nginx/ ├── access.log # Access logs └── error.log # Error logs

/var/www/html/ # Default document root └── index.nginx-debian.html

/usr/share/nginx/html/ # Alternative document root

4.2. Directory structure on CentOS/RHEL

/etc/nginx/
├── nginx.conf                # Main configuration file
├── mime.types
├── fastcgi_params
├── conf.d/                   # Virtual host configs
│   └── default.conf
└── default.d/

/var/log/nginx/ ├── access.log └── error.log

/usr/share/nginx/html/ # Document root └── index.html

4.3. Basic nginx.conf configuration file

# User running Nginx
user www-data;

Number of worker processes (usually = number of CPU cores)

worker_processes auto;

PID file

pid /run/nginx.pid;

Load dynamic modules

include /etc/nginx/modules-enabled/*.conf;

events { # Maximum connections per worker worker_connections 768;

# Event method (epoll for Linux)
use epoll;

}

http { ## # Basic Settings ## sendfile on; tcp_nopush on; types_hash_max_size 2048;

# MIME types
include /etc/nginx/mime.types;
default_type application/octet-stream;

##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;

##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";

##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;

}

4.4. Sample Virtual Host file

server {
# Listening port
listen 80;
listen [::]:80;

# Domain name
server_name example.com www.example.com;

# Document root
root /var/www/example.com;
index index.html index.htm;

# Access and error logs
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;

# Location block
location / {
    try_files $uri $uri/ =404;
}

# Deny access to .htaccess
location ~ /\.ht {
    deny all;
}

}


5. Starting, Stopping, and Reloading Nginx

5.1. Manage with systemctl (Linux)

# Start Nginx
sudo systemctl start nginx

Stop Nginx

sudo systemctl stop nginx

Restart Nginx

sudo systemctl restart nginx

Reload configuration (no downtime)

sudo systemctl reload nginx

Check status

sudo systemctl status nginx

Enable auto-start on boot

sudo systemctl enable nginx

Disable auto-start

sudo systemctl disable nginx

5.2. Manage with nginx command

# Test configuration (very important before reloading)
sudo nginx -t

Test and show config

sudo nginx -T

Reload configuration

sudo nginx -s reload

Stop gracefully (wait for current requests to finish)

sudo nginx -s quit

Stop immediately

sudo nginx -s stop

Reopen log files (after log rotation)

sudo nginx -s reopen

View version and compile options

nginx -V

5.3. Difference between reload, restart, and stop

reload:

  • No downtime
  • Nginx re-reads the configuration
  • Old worker processes finish their current requests then shut down
  • New worker processes are created with the new configuration
  • Use when: Changing configuration, adding/modifying virtual hosts
sudo nginx -s reload

or

sudo systemctl reload nginx

restart:

  • Has downtime (brief)
  • Fully stops then starts again
  • All connections are dropped
  • Use when: Installing new modules, major changes
sudo systemctl restart nginx

stop vs quit:

# Stop immediately (kill connections)
sudo nginx -s stop

Quit gracefully (wait for requests to finish)

sudo nginx -s quit

5.4. Checking that Nginx is running

# Check process
ps aux | grep nginx

Check listening ports

sudo netstat -tulpn | grep nginx

or

sudo ss -tulpn | grep nginx

Check version

nginx -v

Test access

curl http://localhost

or

curl -I http://localhost

5.5. Basic Troubleshooting

Error: nginx.conf test failed

# Check detailed error
sudo nginx -t

View error log

sudo tail -f /var/log/nginx/error.log

Error: Port 80 already in use

# See which process is using port 80
sudo lsof -i :80

or

sudo netstat -tulpn | grep :80

Kill the process if needed

sudo kill -9 <PID>

Error: Permission denied

# Check user in nginx.conf
grep user /etc/nginx/nginx.conf

Check directory permissions

ls -la /var/www/html

Fix ownership

sudo chown -R www-data:www-data /var/www/html

Cannot access via browser:

# Check firewall (Ubuntu/Debian)
sudo ufw status
sudo ufw allow 'Nginx Full'

Check firewall (CentOS)

sudo firewall-cmd --list-all sudo firewall-cmd --permanent --add-service=http sudo firewall-cmd --reload

Check SELinux (CentOS)

sudo getenforce sudo setenforce 0 # Temporarily disable to test


6. Practice Exercises

Exercise 1: Install and verify

  1. Install Nginx on your operating system
  2. Check the version and status
  3. Visit http://localhost and view the default welcome page
  4. Find and view the access.log file

Exercise 2: Get familiar with commands

  1. Test configuration: nginx -t
  2. Reload Nginx
  3. Stop and restart Nginx
  4. Check running processes

Exercise 3: Explore the directory structure

  1. Open nginx.conf and read the directives
  2. Find the document root in the default virtual host
  3. Create a simple HTML file in the document root
  4. Access the file via browser

Exercise 4: Intentional error fixing

  1. Add an invalid syntax line to nginx.conf
  2. Run nginx -t to see the error
  3. Fix the error and test again

Summary

In this lesson, you learned:

  • ✅ What Nginx is and its event-driven architecture
  • ✅ Nginx vs Apache comparison
  • ✅ Installing Nginx on multiple operating systems
  • ✅ Directory structure and configuration files
  • ✅ Basic Nginx management commands

Next lesson: We will dive deeper into Nginx configuration, exploring contexts, directives, virtual hosts, and serving static files.