Tóm tắt: Khắc phục nhanh trong 30 giây
Cảnh báo này xuất hiện khi cùng một server_name xuất hiện trong nhiều tệp cấu hình cho cùng một cổng. Nginx sẽ chỉ đơn giản là chọn tệp đầu tiên mà nó tải và bỏ qua mọi phiên bản khác.
- Tìm các mục trùng lặp:
sudo grep -ri "example.com" /etc/nginx/ - Xóa mục
server_namebị thừa hoặc hợp nhất các tệp. - Kiểm tra cú pháp của bạn:
sudo nginx -t. - Áp dụng các thay đổi:
sudo systemctl reload nginx.
Tại sao Nginx lại bỏ qua cấu hình của bạn
Hãy coi Nginx như một bộ điều phối giao thông. Nó sử dụng chỉ thị server_name để quyết định thư mục hoặc proxy nào sẽ xử lý yêu cầu đến. Nếu bạn định nghĩa example.com ở hai nơi khác nhau, Nginx sẽ bị nhầm lẫn.
Nginx không thể ánh xạ một tên miền duy nhất vào hai khối logic khác nhau cùng một lúc. Để duy trì hoạt động, nó sẽ chọn cấu hình đầu tiên mà nó gặp—thường là cấu hình đứng đầu theo thứ tự bảng chữ cái trong /etc/nginx/sites-enabled/. Sau đó, nó sẽ loại bỏ các cấu hình còn lại. Đây là lý do tại sao các cập nhật mới nhất của bạn có thể không hiển thị trên trình duyệt.
Các kịch bản thường gặp
- Sơ suất khi sao chép và dán: Bạn đã nhân bản
site-a.confđể tạosite-b.confnhưng quên cập nhật tên miền bên trong tệp. - Xung đột với tệp mặc định: Một tệp
defaulthoặc000-defaulttrong thư mục cấu hình của bạn vẫn đang chiếm dụng tên miền mà bạn đang cố gắng chuyển sang một tệp mới. - Sự can thiệp của tệp sao lưu: Bạn để lại tệp
mysite.conf.baktrong thư mục mà Nginx quét qua. Nếunginx.confcủa bạn bao gồm*.conf, nó sẽ tải cả tệp đang hoạt động và tệp sao lưu. - Trùng lặp cổng: Bạn vô tình định nghĩa cùng một tên miền hai lần cho cổng 443 (SSL) trong khi cố gắng thiết lập chuyển hướng.
Các bước khắc phục sự cố
1. Tìm nhanh các mục trùng lặp
Đừng lãng phí thời gian mở từng tệp theo cách thủ công. Hãy sử dụng grep để tìm kiếm trong toàn bộ thư mục cấu hình. Cờ -r giúp tìm kiếm đệ quy và -i để bỏ qua phân biệt chữ hoa chữ thường.
# Tìm kiếm tên miền cụ thể của bạn
sudo grep -ri "example.com" /etc/nginx/
Kết quả đầu ra điển hình hiển thị xung đột sẽ trông như thế này:
/etc/nginx/sites-enabled/prod-site.conf: server_name example.com;
/etc/nginx/sites-enabled/old-site.conf: server_name example.com;
Trong trường hợp này, old-site.conf chính là "thủ phạm" chiếm dụng lưu lượng truy cập từ tệp production của bạn.
2. Kiểm tra cấu hình mặc định (Catch-all)
Nếu tên miền không xuất hiện hai lần trong kết quả grep, hãy kiểm tra xem có máy chủ mặc định nào đang hoạt động như một wildcard (ký tự đại diện) hay không. Chạy lệnh này để xem máy chủ mặc định của bạn đang làm gì:
grep -r "default_server" /etc/nginx/sites-enabled/
3. Giải quyết xung đột
Khi bạn đã tìm thấy hai tệp đang "tranh chấp" tên miền, bạn có hai lựa chọn:
Tùy chọn A: Gỡ bỏ cấu hình cũ
Nếu old-site.conf là tàn dư từ một thiết lập trước đó, hãy xóa liên kết tượng trưng (symlink) của nó để ngăn Nginx tải tệp này:
sudo rm /etc/nginx/sites-enabled/old-site.conf
Tùy chọn B: Hợp nhất các bí danh
Nếu bạn muốn một trang web phản hồi với nhiều tên gọi khác nhau, hãy đặt tất cả chúng vào một khối server. Phân tách chúng bằng khoảng trắng trên một dòng duy nhất:
server {
listen 443 ssl;
server_name example.com www.example.com dev.example.com;
# ... phần còn lại của cấu hình
}
4. Kiểm tra và Tải lại
Luôn xác minh các thay đổi của bạn trước khi áp dụng chúng. Chỉ một dấu chấm phẩy bị thiếu cũng có thể làm hỏng toàn bộ máy chủ web của bạn. Hãy chạy trình kiểm tra nội bộ của Nginx:
sudo nginx -t
Nếu kết quả thông báo test is successful, hãy tải lại dịch vụ. Việc tải lại (reload) an toàn hơn khởi động lại (restart) vì nó không làm ngắt các kết nối hiện tại.
sudo systemctl reload nginx
Các vấn đề riêng biệt trên Docker
Khi sử dụng các hình ảnh (image) chính thức như nginx:alpine hoặc nginx:latest, một cấu hình mặc định thường được tích hợp sẵn tại /etc/nginx/conf.d/default.conf. Nếu bạn gắn (mount) các tệp cấu hình của riêng mình vào thư mục đó mà không ghi đè lên tệp mặc định, bạn sẽ gặp phải xung đột này ngay lập tức.
Để tìm xung đột bên trong một container đang chạy, hãy sử dụng:
docker exec -it grep -r "example.com" /etc/nginx/
Khắc phục điều này bằng cách đảm bảo Dockerfile của bạn xóa cấu hình mặc định hoặc bằng cách gắn tệp của bạn trực tiếp đè lên /etc/nginx/conf.d/default.conf.
Cách xác minh việc khắc phục đã thành công
Bạn có thể chứng minh Nginx đang sử dụng đúng tệp bằng cách thêm một header theo dõi tùy chỉnh vào cấu hình đang hoạt động của mình:
server {
server_name example.com;
add_header X-Config-Status "Correct-File-Loaded";
# ...
}
Sau khi tải lại, hãy kiểm tra các response header bằng curl:
curl -I https://example.com
Nếu bạn thấy X-Config-Status: Correct-File-Loaded, bạn đã giải quyết xung đột thành công.

