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.

12 min read
Bài 2: Cấu hình Cơ bản Nginx

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: Root khác với root
# Đú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:

  1. = - Exact match (cao nhất)
  2. ^~ - Prefix match (stop regex)
  3. ~ hoặc ~* - Regex match (theo thứ tự xuất hiện trong file)
  4. 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

  1. Tạo virtual host cho mysite.local
  2. Document root: /var/www/mysite
  3. Tạo file index.html với nội dung tùy ý
  4. Thêm vào /etc/hosts và test

Bài tập 2: Static File Server

  1. Tạo cấu trúc thư mục:
/var/www/static/
├── index.html
├── css/style.css
├── js/app.js
└── images/logo.png
  1. Cấu hình Nginx serve các file này
  2. Set cache headers khác nhau cho từng loại file

Bài tập 3: Directory Listing

  1. Tạo virtual host cho files.local
  2. Bật autoindex
  3. Tùy chỉnh format và styling
  4. Test với nhiều files

Bài tập 4: Custom Error Pages

  1. Tạo custom 404 và 500 pages
  2. Apply cho một virtual host
  3. Test bằng cách truy cập URL không tồn tại
  4. Test 500 error (có thể fake bằng return 500)

Bài tập 5: Multiple Virtual Hosts

  1. Tạo 3 virtual hosts:
    • site1.local/var/www/site1
    • site2.local/var/www/site2
    • blog.site1.local/var/www/blog
  2. Mỗi site có content khác nhau
  3. 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

  1. Tổ chức file cấu hình:
/etc/nginx/
├── nginx.conf (main config)
├── conf.d/ (global configs)
└── sites-available/ (individual sites)
  1. Comment rõ ràng:
# Block spam bots
if ($http_user_agent ~* (bot|crawler|spider)) {
    return 403;
}
  1. Sử dụng include:
http {
    include /etc/nginx/mime.types;
    include /etc/nginx/conf.d/*.conf;
}
  1. Test trước khi reload:
sudo nginx -t && sudo systemctl reload nginx
  1. 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.

configuration Nginx configuration-management NginxConf ServerBlocks VirtualHost StaticFiles Context Dircetive Location

Đánh dấu hoàn thành (Bài 2: Cấu hình Cơ bản Nginx)