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:
- Master Process: A single master process reads and evaluates the configuration, and manages worker processes
- Worker Processes: Multiple worker processes handle the actual connections
- 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 updateInstall 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-keyringImport official nginx signing key
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor
| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/nullSetup repository
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg]
http://nginx.org/packages/ubuntulsb_release -csnginx"
| sudo tee /etc/apt/sources.list.d/nginx.listUpdate 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 -yCentOS 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 EOFInstall
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
- Visit: http://nginx.org/en/download.html
- Download the Windows version (nginx-x.x.x.zip)
Step 2: Extract and run
# Extract to C:\nginxOpen Command Prompt as Administrator
cd C:\nginx
Start Nginx
start nginx
Or
nginx.exe
Managing Nginx on Windows:
# Check version nginx -vTest 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 nginxStop 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 -tTest 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 reloador
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 stopQuit gracefully (wait for requests to finish)
sudo nginx -s quit
5.4. Checking that Nginx is running
# Check process ps aux | grep nginxCheck 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 -tView 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 :80or
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.confCheck 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
- Install Nginx on your operating system
- Check the version and status
- Visit http://localhost and view the default welcome page
- Find and view the access.log file
Exercise 2: Get familiar with commands
- Test configuration:
nginx -t - Reload Nginx
- Stop and restart Nginx
- Check running processes
Exercise 3: Explore the directory structure
- Open nginx.conf and read the directives
- Find the document root in the default virtual host
- Create a simple HTML file in the document root
- Access the file via browser
Exercise 4: Intentional error fixing
- Add an invalid syntax line to nginx.conf
- Run
nginx -tto see the error - 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.