Cài đặt và cấu hình Nginx trên Ubuntu 22.04: Web Server thực chiến từ A đến Z

Linux tutorial - IT technology blog
Linux tutorial - IT technology blog

Chạy Nginx trong 5 phút — làm trước, hiểu sau

Mở terminal lên, chạy 3 lệnh này:

sudo apt update
sudo apt install nginx -y
sudo systemctl start nginx

Xong. Mở trình duyệt, nhập http://localhost hoặc IP server — trang mặc định Nginx hiện ra ngay. Đơn giản vậy thôi.

Nhưng dừng ở đây thì web server của bạn chỉ phục vụ được trang demo. Phần còn lại giải thích tại sao Nginx được tin dùng rộng rãi và cách cấu hình để chạy website thật.

Nginx là gì và tại sao không dùng Apache?

Search “web server Linux” là thấy 2 cái tên: Nginx và Apache. Mình dùng cả hai nhiều năm và câu trả lời thành thật là: tùy bài toán — nhưng với server hiện đại thì Nginx thắng ở hầu hết trường hợp.

Apache ra đời năm 1995, xử lý mỗi request bằng một thread riêng. Ổn khi traffic thấp, nhưng khi có 1.000 kết nối đồng thời, Apache cần 1.000 thread — RAM bốc hơi rất nhanh.

Nginx sinh ra năm 2004 để giải quyết đúng vấn đề đó. Kiến trúc event-driven cho phép một process xử lý hàng nghìn kết nối cùng lúc. Trên server 4GB RAM mình đang quản lý, Nginx worker process ngốn khoảng 10–15MB RAM. Chạy Apache với traffic tương đương? Dễ vọt lên 100MB+.

Nginx cũng làm được nhiều hơn là web server thuần túy: reverse proxy, load balancer, HTTP cache — tất cả trong một package gọn nhẹ.

Cài đặt Nginx trên Ubuntu 22.04 đúng cách

Bước 1: Cập nhật và cài đặt

sudo apt update
sudo apt install nginx -y

Bước 2: Kiểm tra trạng thái

sudo systemctl status nginx

Thấy Active: active (running) màu xanh là ổn. Nếu chưa tự khởi động:

sudo systemctl start nginx
sudo systemctl enable nginx  # tự khởi động khi reboot

Bước 3: Mở firewall

Ubuntu 22.04 dùng UFW. Cho phép Nginx đi qua:

sudo ufw allow 'Nginx Full'
sudo ufw status

Nginx Full mở cả HTTP (port 80) lẫn HTTPS (port 443). Môi trường test chỉ cần HTTP? Dùng Nginx HTTP thay thế.

Cấu trúc thư mục Nginx — biết để không bị lạc

Biết file nào nằm ở đâu trước, không mất công tìm kiếm sau:

  • /etc/nginx/nginx.conf — file cấu hình chính, thường không cần đụng vào
  • /etc/nginx/sites-available/ — chứa config của từng website (kể cả site chưa bật)
  • /etc/nginx/sites-enabled/ — symlink đến sites-available, chỉ những site đang chạy
  • /var/www/html/ — thư mục web mặc định
  • /var/log/nginx/ — log file (access.log và error.log)

Cơ chế này khá thông minh: tạo config trong sites-available, rồi tạo symlink sang sites-enabled để bật. Muốn tắt website tạm thời, xóa symlink — không cần xóa file gốc. Rất tiện khi maintenance.

Cấu hình Virtual Host — host nhiều website trên 1 server

Nhiều người bỏ qua phần này rồi sau đó gặp rắc rối. Virtual host cho phép chạy nhiều website trên cùng 1 server, phân biệt nhau bằng domain name.

Tạo thư mục và nội dung cho website

sudo mkdir -p /var/www/mysite.com/html
sudo chown -R $USER:$USER /var/www/mysite.com/html
echo "<h1>Website của tôi</h1>" | sudo tee /var/www/mysite.com/html/index.html

Tạo file cấu hình Nginx

sudo nano /etc/nginx/sites-available/mysite.com

Nội dung file:

server {
    listen 80;
    listen [::]:80;

    server_name mysite.com www.mysite.com;
    root /var/www/mysite.com/html;
    index index.html index.htm;

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

    access_log /var/log/nginx/mysite.access.log;
    error_log /var/log/nginx/mysite.error.log;
}

Bật website và reload

sudo ln -s /etc/nginx/sites-available/mysite.com /etc/nginx/sites-enabled/
sudo nginx -t          # kiểm tra syntax TRƯỚC khi reload
sudo systemctl reload nginx

Lệnh nginx -t rất quan trọng — luôn chạy trước khi reload để tránh crash web server vì lỗi syntax config.

Nâng cao: Nginx làm Reverse Proxy cho ứng dụng backend

Scenario quen thuộc nhất trên production: ứng dụng Node.js/Python/Go đang chạy trên port 3000, muốn expose ra ngoài qua port 80/443 với domain. Nginx đứng ở giữa làm cầu nối.

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

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        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_cache_bypass $http_upgrade;
    }
}

Hai header X-Real-IPX-Forwarded-For giúp ứng dụng backend nhận được IP thật của client, không phải IP của Nginx. Thiếu dòng này, toàn bộ request đều đến từ 127.0.0.1 — debug log rất khó chịu.

Bật HTTPS với Let’s Encrypt — miễn phí và tự động

Chrome đánh dấu “Not Secure” với mọi site không có HTTPS, ảnh hưởng cả UX lẫn thứ hạng SEO. Certbot xử lý việc này hoàn toàn miễn phí:

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d mysite.com -d www.mysite.com

Certbot tự sửa file config Nginx để thêm SSL. Chứng chỉ tự gia hạn mỗi 90 ngày — kiểm tra bằng:

sudo certbot renew --dry-run

Tips thực tế từ người dùng hàng ngày

1. Log là công cụ debug tốt nhất

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

Website có vấn đề? Mở 2 terminal: một theo dõi error.log, một reproduce lỗi. Hầu hết sự cố đều lộ ra ngay.

2. Tối ưu performance với Gzip và bảo mật cơ bản

Thêm vào block http {} trong /etc/nginx/nginx.conf:

gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml;
gzip_min_length 1000;

keepalive_timeout 65;
server_tokens off;  # ẩn version Nginx trong response header

gzip on nén response trước khi gửi về client — giảm bandwidth 60–70% với file HTML/CSS/JS. server_tokens off ẩn version Nginx khỏi response header, bớt thông tin cho kẻ tấn công dò lỗ hổng.

3. Rate limiting — chặn spam và brute force

http {
    limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;

    server {
        location /api/ {
            limit_req zone=api burst=20 nodelay;
        }
    }
}

Config này giới hạn mỗi IP chỉ được gửi 10 request/giây đến /api/. Vài dòng config, chặn được phần lớn brute force và flood request cơ bản mà không cần thêm công cụ nào.

4. Reload không downtime — bí quyết trên production

# Kiểm tra syntax
sudo nginx -t

# Reload không downtime
sudo systemctl reload nginx

Khác với restart, reload không dừng Nginx — nó đọc config mới và áp dụng mà không cắt đứt kết nối hiện tại. Trên production, luôn dùng reload thay vì restart.

Kết

Nginx thực ra bớt đáng sợ hơn tiếng tăm của nó. Cài xong trong 2 phút. Thêm 5 phút là virtual host chạy ngon. Reverse proxy hay SSL — chỉ là thêm vài block config.

Ba thứ cần khắc cố: luôn chạy nginx -t trước khi reload, dùng reload thay vì restart, và đừng coi nhẹ log file — đó là nơi đầu tiên cần nhìn khi có sự cố.

Share: