Bài 2: Cấu hình Cơ bản Nginx
Bài học về cấu hình Nginx với cú pháp nginx.conf, context (http/server/location), directive cơ bản. Hướng dẫn tạo virtual hosts, serving static files, index files, autoindex và custom error pages. Bao gồm ví dụ thực tế và best practices cho production.
1. Cú pháp file cấu hình nginx.conf
File nginx.conf là trái tim của Nginx, nơi định nghĩa toàn bộ cách hoạt động của web server. Hiểu rõ cú pháp cấu hình là bước đầu tiên để làm chủ Nginx.
1.1. Cấu trúc cơ bản
# Directive đơn giản (simple directive)
worker_processes 4;
# Directive block (block directive)
events {
worker_connections 1024;
}
# Block lồng nhau (nested blocks)
http {
server {
location / {
root /var/www/html;
}
}
}
1.2. Quy tắc cú pháp
1. Directives:
- Mỗi directive kết thúc bằng dấu chấm phẩy
; - Directives có thể là simple (một dòng) hoặc block (có dấu
{}) - Case-sensitive:
Rootkhác vớiroot
# Đúng
worker_processes 2;
# Sai - thiếu dấu chấm phẩy
worker_processes 2
# Sai - case sai
Worker_Processes 2;
2. Comments:
# Đây là comment một dòng
worker_processes 4; # Comment cuối dòng
# Không có comment nhiều dòng trong Nginx
# Phải dùng # cho mỗi dòng
3. Include files:
# Include file khác
include /etc/nginx/mime.types;
# Include nhiều files với wildcard
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
4. Variables:
# Nginx có nhiều biến built-in
# Bắt đầu bằng $
$remote_addr # IP của client
$request_uri # URI được request
$host # Hostname
# Ví dụ sử dụng
location / {
return 200 "Your IP: $remote_addr\n";
}
5. String values:
# Không cần quotes cho giá trị đơn giản
root /var/www/html;
# Cần quotes nếu có space hoặc ký tự đặc biệt
error_log "/var/log/nginx/error.log" warn;
add_header X-Custom-Header "Hello World";
# Có thể dùng single hoặc double quotes
root '/var/www/html';
root "/var/www/html";
1.3. Units và sizes
# Time units
client_body_timeout 60s; # seconds (mặc định)
client_body_timeout 60; # cũng là seconds
client_body_timeout 60m; # minutes
client_body_timeout 1h; # hours
client_body_timeout 1d; # days
# Size units
client_max_body_size 10m; # megabytes
client_max_body_size 10M; # cũng là megabytes
client_max_body_size 1g; # gigabytes
client_max_body_size 1024k; # kilobytes
client_max_body_size 1048576; # bytes (không có unit)
1.4. Measurement units
# Không có unit = bytes
client_max_body_size 1048576; # 1MB
# k/K = kilobytes
client_max_body_size 1024k;
# m/M = megabytes
client_max_body_size 1m;
# g/G = gigabytes (Nginx 0.7.0+)
client_max_body_size 1g;
2. Context và Directive
Nginx sử dụng hệ thống context (ngữ cảnh) để tổ chức cấu hình theo cấp độ. Mỗi context định nghĩa phạm vi áp dụng của các directives.
2.1. Các Context chính
# MAIN CONTEXT (global)
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
# EVENTS CONTEXT
events {
worker_connections 1024;
use epoll;
}
# HTTP CONTEXT
http {
# Áp dụng cho tất cả HTTP traffic
# SERVER CONTEXT
server {
# Áp dụng cho một virtual host cụ thể
# LOCATION CONTEXT
location / {
# Áp dụng cho một URL pattern cụ thể
}
}
}
# STREAM CONTEXT (cho TCP/UDP)
stream {
server {
listen 3306;
}
}
# MAIL CONTEXT (cho mail proxy)
mail {
server {
listen 25;
}
}
2.2. HTTP Context - Cấu hình toàn cục
http {
# MIME types
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Logging
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;
# Performance
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# Gzip compression
gzip on;
gzip_vary on;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# Include server blocks
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
2.3. Server Context - Virtual Host
http {
# Server block 1
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com;
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
}
# Server block 2
server {
listen 80;
server_name blog.example.com;
root /var/www/blog;
}
# Default server (catch-all)
server {
listen 80 default_server;
server_name _;
return 444; # Close connection
}
}
2.4. Location Context - URL Matching
server {
listen 80;
server_name example.com;
root /var/www/html;
# Exact match
location = /about {
# Chỉ match đúng /about
}
# Prefix match
location /images/ {
# Match /images/*, /images/photo.jpg, etc.
}
# Regex match (case-sensitive)
location ~ \.(jpg|png|gif)$ {
# Match file kết thúc bằng .jpg, .png, .gif
}
# Regex match (case-insensitive)
location ~* \.(jpg|png|gif)$ {
# Match JPG, jpg, JpG, etc.
}
# Prefix match (stop regex checking)
location ^~ /api/ {
# Match /api/* và không check regex
}
# Default location
location / {
# Match tất cả nếu không có match nào khác
}
}
2.5. Priority của Location Matching
Nginx xử lý location theo thứ tự ưu tiên:
=- Exact match (cao nhất)^~- Prefix match (stop regex)~hoặc~*- Regex match (theo thứ tự xuất hiện trong file)- No modifier - Prefix match (thấp nhất)
Ví dụ minh họa:
server {
listen 80;
server_name example.com;
# Priority 1 - Exact match
location = /test {
return 200 "Exact match: /test\n";
}
# Priority 2 - Prefix (stop regex)
location ^~ /test {
return 200 "Prefix match (^~): /test*\n";
}
# Priority 3 - Regex (case-insensitive)
location ~* ^/test {
return 200 "Regex match (~*): /test*\n";
}
# Priority 4 - Prefix match
location /test {
return 200 "Prefix match: /test*\n";
}
# Default
location / {
return 200 "Default location\n";
}
}
Test kết quả:
curl http://example.com/test
# → "Exact match: /test"
curl http://example.com/test123
# → "Prefix match (^~): /test*" (vì ^~ stop regex)
# Nếu xóa ^~ location:
curl http://example.com/test123
# → "Regex match (~*): /test*"
3. Cấu hình Virtual Host (Server Blocks)
Virtual hosts cho phép một Nginx server phục vụ nhiều websites/domains khác nhau.
3.1. Tạo Virtual Host đầu tiên
Bước 1: Tạo thư mục cho website
# Tạo document root
sudo mkdir -p /var/www/mysite.com/html
# Tạo thư mục logs
sudo mkdir -p /var/www/mysite.com/logs
# Set ownership
sudo chown -R $USER:$USER /var/www/mysite.com
sudo chmod -R 755 /var/www/mysite.com
Bước 2: Tạo file HTML mẫu
cat > /var/www/mysite.com/html/index.html << 'EOF'
<!DOCTYPE html>
<html>
<head>
<title>Welcome to mysite.com</title>
<style>
body { font-family: Arial, sans-serif; margin: 50px; }
h1 { color: #00539C; }
</style>
</head>
<body>
<h1>Welcome to mysite.com!</h1>
<p>This is my first Nginx virtual host.</p>
</body>
</html>
EOF
Bước 3: Tạo file cấu hình virtual host
# Ubuntu/Debian
sudo nano /etc/nginx/sites-available/mysite.com
# CentOS/RHEL
sudo nano /etc/nginx/conf.d/mysite.com.conf
Nội dung file cấu hình:
server {
# Port và server name
listen 80;
listen [::]:80;
server_name mysite.com www.mysite.com;
# Document root
root /var/www/mysite.com/html;
index index.html index.htm;
# Logs
access_log /var/www/mysite.com/logs/access.log;
error_log /var/www/mysite.com/logs/error.log;
# Main location
location / {
try_files $uri $uri/ =404;
}
# Error pages
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /404.html {
internal;
}
location = /50x.html {
internal;
}
# Deny access to hidden files
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
}
Bước 4: Enable virtual host (Ubuntu/Debian)
# Tạo symlink
sudo ln -s /etc/nginx/sites-available/mysite.com /etc/nginx/sites-enabled/
# Kiểm tra cấu hình
sudo nginx -t
# Reload Nginx
sudo systemctl reload nginx
Bước 5: Cấu hình DNS hoặc hosts file
# Thêm vào /etc/hosts (cho local testing)
sudo nano /etc/hosts
# Thêm dòng:
127.0.0.1 mysite.com www.mysite.com
Bước 6: Test
curl http://mysite.com
# hoặc mở browser: http://mysite.com
3.2. Virtual Host với nhiều domains
# Cấu hình 1: Nhiều domains cho cùng nội dung
server {
listen 80;
server_name mysite.com www.mysite.com example.com www.example.com;
root /var/www/mysite.com/html;
index index.html;
}
# Cấu hình 2: Subdomain
server {
listen 80;
server_name blog.mysite.com;
root /var/www/blog;
index index.html;
}
server {
listen 80;
server_name shop.mysite.com;
root /var/www/shop;
index index.html;
}
# Cấu hình 3: Wildcard subdomain
server {
listen 80;
server_name *.mysite.com;
root /var/www/subdomains/$host;
# $host sẽ chứa subdomain.mysite.com
}
# Cấu hình 4: Regex server name
server {
listen 80;
server_name ~^(www\.)?(?<domain>.+)$;
root /var/www/$domain;
}
3.3. Default Server (Catch-all)
# Default server để handle requests không match
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _; # Underscore = không quan tâm server name
# Option 1: Return 444 (close connection)
return 444;
# Option 2: Return 403 Forbidden
# return 403;
# Option 3: Redirect to main site
# return 301 https://mainsite.com$request_uri;
# Option 4: Show maintenance page
# root /var/www/default;
# index maintenance.html;
}
3.4. Listen directives nâng cao
server {
# IPv4
listen 80;
# IPv6
listen [::]:80;
# Specific IP
listen 192.168.1.100:80;
# Different port
listen 8080;
# Default server
listen 80 default_server;
# SSL
listen 443 ssl;
listen [::]:443 ssl;
# HTTP/2
listen 443 ssl http2;
# Multiple options
listen 80 default_server reuseport;
}
4. Serving Static Files
Nginx rất xuất sắc trong việc phục vụ static content (HTML, CSS, JS, images).
4.1. Cấu hình cơ bản
server {
listen 80;
server_name static.example.com;
# Document root
root /var/www/static;
# Index files
index index.html index.htm;
# Main location
location / {
try_files $uri $uri/ =404;
}
}
Cấu trúc thư mục:
/var/www/static/
├── index.html
├── css/
│ ├── style.css
│ └── bootstrap.css
├── js/
│ ├── app.js
│ └── jquery.js
└── images/
├── logo.png
└── background.jpg
Requests được handle:
http://static.example.com/ → /var/www/static/index.html
http://static.example.com/css/style.css → /var/www/static/css/style.css
http://static.example.com/images/logo.png → /var/www/static/images/logo.png
4.2. Root vs Alias
Root directive:
location /images/ {
root /var/www/static;
}
# Request: /images/photo.jpg
# File path: /var/www/static/images/photo.jpg
# (root + location path)
Alias directive:
location /images/ {
alias /var/www/photos/;
}
# Request: /images/photo.jpg
# File path: /var/www/photos/photo.jpg
# (alias thay thế location path)
Ví dụ chi tiết:
server {
listen 80;
server_name example.com;
# Sử dụng root
location /static/ {
root /var/www;
}
# /static/style.css → /var/www/static/style.css
# Sử dụng alias
location /assets/ {
alias /var/www/static/;
}
# /assets/style.css → /var/www/static/style.css
# Alias cho exact path
location = /favicon.ico {
alias /var/www/icons/favicon.ico;
}
}
Lưu ý: Khi dùng alias, location path phải kết thúc bằng / nếu alias cũng kết thúc bằng /.
4.3. Try_files directive
# Cú pháp
try_files file ... uri;
try_files file ... =code;
# Ví dụ 1: Check file, folder, rồi 404
location / {
try_files $uri $uri/ =404;
}
# Ví dụ 2: Fallback to index.html (SPA)
location / {
try_files $uri $uri/ /index.html;
}
# Ví dụ 3: Check multiple files
location / {
try_files $uri $uri/index.html $uri.html =404;
}
# Ví dụ 4: Fallback to backend
location / {
try_files $uri $uri/ @backend;
}
location @backend {
proxy_pass http://localhost:3000;
}
4.4. Cấu hình cho từng loại file
server {
listen 80;
server_name cdn.example.com;
root /var/www/cdn;
# HTML files
location ~ \.html$ {
add_header Cache-Control "public, max-age=3600";
}
# CSS và JavaScript
location ~ \.(css|js)$ {
add_header Cache-Control "public, max-age=31536000";
access_log off;
}
# Images
location ~ \.(jpg|jpeg|png|gif|ico|svg|webp)$ {
add_header Cache-Control "public, max-age=31536000";
access_log off;
expires 1y;
}
# Fonts
location ~ \.(woff|woff2|ttf|otf|eot)$ {
add_header Cache-Control "public, max-age=31536000";
add_header Access-Control-Allow-Origin "*";
access_log off;
}
# Videos
location ~ \.(mp4|webm|ogg)$ {
add_header Cache-Control "public, max-age=31536000";
mp4; # Enable MP4 streaming
access_log off;
}
# Downloads
location /downloads/ {
add_header Content-Disposition "attachment";
}
}
4.5. Security cho static files
server {
listen 80;
root /var/www/html;
# Deny access to hidden files
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# Deny access to backup files
location ~ ~$ {
deny all;
access_log off;
log_not_found off;
}
# Deny access to config files
location ~ \.(conf|config|yml|yaml|ini)$ {
deny all;
}
# Protect sensitive directories
location ~ ^/(\.git|\.svn|\.env) {
deny all;
}
}
5. Cấu hình Index Files và Autoindex
5.1. Index directive
# Cú pháp
index file ...;
# Ví dụ 1: Default index
server {
listen 80;
root /var/www/html;
index index.html index.htm;
}
# Ví dụ 2: Nhiều index files (theo thứ tự)
server {
listen 80;
root /var/www/html;
index index.php index.html index.htm default.html;
}
# Ví dụ 3: Index khác nhau cho từng location
server {
listen 80;
root /var/www/html;
location / {
index index.html;
}
location /blog/ {
index index.php;
}
location /docs/ {
index readme.md index.html;
}
}
5.2. Autoindex (Directory Listing)
# Bật autoindex
server {
listen 80;
server_name files.example.com;
root /var/www/files;
location / {
autoindex on;
}
}
# Cấu hình autoindex chi tiết
location /downloads/ {
autoindex on; # Bật directory listing
autoindex_exact_size off; # Hiển thị size dạng KB, MB thay vì bytes
autoindex_localtime on; # Hiển thị local time thay vì GMT
autoindex_format html; # Format: html, xml, json, jsonp
}
# Ví dụ với format JSON
location /api/files/ {
autoindex on;
autoindex_format json;
}
Output autoindex:
Index of /downloads/
../
file1.pdf 23-Nov-2024 10:30 2.5M
file2.zip 22-Nov-2024 15:45 15M
folder/ 20-Nov-2024 09:00 -
5.3. Custom autoindex styling
server {
listen 80;
root /var/www/files;
location / {
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
# Add custom header/footer
add_before_body /autoindex/header.html;
add_after_body /autoindex/footer.html;
}
location /autoindex/ {
internal;
alias /var/www/autoindex/;
}
}
File header.html:
<!DOCTYPE html>
<html>
<head>
<title>File Directory</title>
<style>
body { font-family: Arial; margin: 20px; }
h1 { color: #333; }
a { color: #0066cc; text-decoration: none; }
a:hover { text-decoration: underline; }
</style>
</head>
<body>
<h1>File Directory</h1>
<hr>
File footer.html:
<hr>
<p>© 2024 My Company</p>
</body>
</html>
6. Error Pages Tùy chỉnh
6.1. Cấu hình cơ bản
server {
listen 80;
server_name example.com;
root /var/www/html;
# Custom error pages
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
# Location cho error pages
location = /404.html {
internal; # Chỉ accessible internally
}
location = /50x.html {
internal;
}
}
6.2. Error pages chi tiết
Tạo file 404.html:
cat > /var/www/html/404.html << 'EOF'
<!DOCTYPE html>
<html>
<head>
<title>404 - Page Not Found</title>
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
padding: 50px;
background: #f5f5f5;
}
h1 { font-size: 72px; color: #e74c3c; }
p { font-size: 24px; color: #555; }
a { color: #3498db; text-decoration: none; }
</style>
</head>
<body>
<h1>404</h1>
<p>Oops! Page not found.</p>
<p><a href="/">← Go back home</a></p>
</body>
</html>
EOF
Tạo file 50x.html:
cat > /var/www/html/50x.html << 'EOF'
<!DOCTYPE html>
<html>
<head>
<title>500 - Server Error</title>
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
padding: 50px;
background: #f5f5f5;
}
h1 { font-size: 72px; color: #e67e22; }
p { font-size: 24px; color: #555; }
</style>
</head>
<body>
<h1>500</h1>
<p>Internal Server Error</p>
<p>We're working on it!</p>
</body>
</html>
EOF
6.3. Error pages nâng cao
server {
listen 80;
server_name example.com;
root /var/www/html;
# Error pages cho từng location
location / {
error_page 404 /errors/404.html;
}
location /api/ {
error_page 404 /errors/api-404.json;
error_page 500 /errors/api-500.json;
}
# Error page với custom message
location /special/ {
error_page 404 =200 /custom-404.html;
# =200 override status code
}
# Redirect to external error page
location /old-site/ {
error_page 404 = @external_error;
}
location @external_error {
return 302 https://example.com/error-handler;
}
# Error page với variable
location /dynamic/ {
error_page 404 /404.html?page=$uri;
}
# Named location cho errors
error_page 404 = @notfound;
location @notfound {
return 404 "Custom 404 message\n";
}
}
6.4. Error log với format
http {
# Define custom error log format
log_format error_log '[$time_local] $status $request '
'Client: $remote_addr '
'Server: $server_name';
server {
listen 80;
server_name example.com;
# Use custom format
error_log /var/log/nginx/example.error.log error_log;
# Different log level
error_log /var/log/nginx/debug.log debug;
}
}
7. Bài tập thực hành
Bài tập 1: Tạo Virtual Host
- Tạo virtual host cho
mysite.local - Document root:
/var/www/mysite - Tạo file index.html với nội dung tùy ý
- Thêm vào /etc/hosts và test
Bài tập 2: Static File Server
- Tạo cấu trúc thư mục:
/var/www/static/
├── index.html
├── css/style.css
├── js/app.js
└── images/logo.png
- Cấu hình Nginx serve các file này
- Set cache headers khác nhau cho từng loại file
Bài tập 3: Directory Listing
- Tạo virtual host cho
files.local - Bật autoindex
- Tùy chỉnh format và styling
- Test với nhiều files
Bài tập 4: Custom Error Pages
- Tạo custom 404 và 500 pages
- Apply cho một virtual host
- Test bằng cách truy cập URL không tồn tại
- Test 500 error (có thể fake bằng return 500)
Bài tập 5: Multiple Virtual Hosts
- Tạo 3 virtual hosts:
site1.local→/var/www/site1site2.local→/var/www/site2blog.site1.local→/var/www/blog
- Mỗi site có content khác nhau
- Configure và test tất cả
8. Troubleshooting thường gặp
Lỗi 1: 403 Forbidden
# Nguyên nhân: Permission
ls -la /var/www/html
# Fix: Set đúng ownership
sudo chown -R www-data:www-data /var/www/html
sudo chmod -R 755 /var/www/html
# Nguyên nhân: SELinux (CentOS)
sudo setenforce 0
Lỗi 2: 404 Not Found
# Check root directive
location / {
root /var/www/html; # Đường dẫn đúng chưa?
index index.html; # File có tồn tại không?
}
# Check với curl
curl -I http://example.com
Lỗi 3: Cấu hình không reload
# Test config trước
sudo nginx -t
# Nếu OK thì reload
sudo systemctl reload nginx
# Check error log
sudo tail -f /var/log/nginx/error.log
Lỗi 4: Server name không work
# Check DNS/hosts
cat /etc/hosts
# Check server_name directive
grep server_name /etc/nginx/sites-available/*
# Clear browser cache
# Hoặc test với curl
curl -H "Host: mysite.com" http://localhost
9. Best Practices
- Tổ chức file cấu hình:
/etc/nginx/
├── nginx.conf (main config)
├── conf.d/ (global configs)
└── sites-available/ (individual sites)
- Comment rõ ràng:
# Block spam bots
if ($http_user_agent ~* (bot|crawler|spider)) {
return 403;
}
- Sử dụng include:
http {
include /etc/nginx/mime.types;
include /etc/nginx/conf.d/*.conf;
}
- Test trước khi reload:
sudo nginx -t && sudo systemctl reload nginx
- Backup configs:
sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup
Tổng kết
Trong bài này, bạn đã học:
- ✅ Cú pháp và cấu trúc nginx.conf
- ✅ Context và directive trong Nginx
- ✅ Tạo và quản lý virtual hosts
- ✅ Serving static files hiệu quả
- ✅ Cấu hình index files và autoindex
- ✅ Tùy chỉnh error pages
Bài tiếp theo: Chúng ta sẽ tìm hiểu về Logging và Monitoring - cách theo dõi và phân tích traffic trên Nginx server.