Thông báo lỗi
Bạn cố gắng khởi động hoặc khởi động lại Nginx, nhưng thay vì thoát ra bình thường, terminal lại hiển thị một loạt thông báo lỗi. Nó thường trông như thế này:
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] still could not bind()
Điều gì đang xảy ra?
Mạng trên Linux rất nghiêm ngặt: tại một thời điểm chỉ có một ứng dụng có thể chiếm dụng một cổng cụ thể. Cổng 80 là luồng tiêu chuẩn cho lưu lượng HTTP. Nếu Nginx cố gắng mở luồng đó và thấy ai đó đã "đỗ" sẵn ở đó, nó sẽ từ bỏ.
Thông thường, "kẻ chiếm giữ" là một trong những trường hợp sau:
- Một tiến trình Nginx "ma" không tắt đúng cách sau khi bị lỗi.
- Apache (httpd) đang chạy ngầm—thường thấy trên các bản cài đặt VPS mới.
- Một Docker container hoặc ứng dụng Node.js đang ánh xạ cổng 80 của máy chủ vào container.
- Các chỉ thị
listen 80;dư thừa trong chính các tệp cấu hình của bạn.
Bước 1: Tìm ra thủ phạm
Bạn cần tìm ID tiến trình (PID) hiện đang chiếm giữ cổng. Lệnh ss là cách nhanh nhất để thực hiện việc này trên các hệ thống Linux hiện đại.
Sử dụng ss (Khuyên dùng)
sudo ss -tulpn | grep :80
Kết quả trả về sẽ tương tự như thế này:
tcp LISTEN 0 511 *:80 *:* users:(("apache2",pid=1234,fd=4))
Sử dụng lsof
Nếu bạn thích dùng lsof, hãy chạy lệnh sau:
sudo lsof -i :80
Các cột COMMAND và PID sẽ cho bạn biết chính xác bạn đang đối đầu với cái gì. Ví dụ: nếu bạn thấy apache2 với PID 1234, bạn đã tìm thấy nguyên nhân gây nghẽn.
Bước 2: Loại bỏ tiến trình gây xung đột
Khi đã có tên hoặc PID, bạn cần dọn đường cho Nginx.
Dừng Apache hoặc các dịch vụ khác
Nếu Apache là bên đang chiếm dụng cổng, hãy dừng và vô hiệu hóa nó để nó không tự khởi động lại sau khi reboot.
# Dành cho Ubuntu/Debian
sudo systemctl stop apache2
sudo systemctl disable apache2
# Dành cho CentOS/RHEL
sudo systemctl stop httpd
sudo systemctl disable httpd
Tắt các tiến trình Nginx bị treo
Đôi khi Nginx bị treo và để lại các tiến trình "zombie". Bạn có thể ép đóng mọi tác vụ liên quan đến Nginx bằng một lệnh duy nhất:
sudo killall -9 nginx
Hãy thận trọng khi sử dụng lệnh này. Nó sẽ chấm dứt tất cả các tiến trình Nginx ngay lập tức mà không lưu trạng thái.
Bước 3: Kiểm tra lại cấu hình
Nếu không có phần mềm nào khác đang chạy trên cổng 80, có thể cấu hình Nginx của bạn đang tự xung đột với chính nó. Điều này thường xảy ra khi hai tệp cấu hình trang web khác nhau trong /etc/nginx/sites-enabled/ đều cố gắng chiếm quyền default_server.
Trước tiên hãy kiểm tra lỗi cú pháp:
sudo nginx -t
Tìm kiếm trong thư mục cấu hình các khai báo trùng lặp cổng 80. Chạy lệnh này để xem mọi tệp đang cố gắng sử dụng cổng đó:
grep -r "listen 80" /etc/nginx/sites-enabled/
Đảm bảo rằng bạn không có hai khối (block) khác nhau cùng cố gắng liên kết với một tổ hợp IP và cổng giống nhau.
Bước 4: Khởi động Nginx
Khi cổng đã được giải phóng, Nginx sẽ khởi động mà không gặp lỗi nào nữa.
sudo systemctl start nginx
Xác minh
Kiểm tra lại trạng thái để đảm bảo nó vẫn đang hoạt động. Nó sẽ hiển thị active (running) bằng chữ màu xanh lá cây.
sudo systemctl status nginx
Bạn cũng có thể xác nhận Nginx hiện là bên sở hữu cổng:
sudo ss -tulpn | grep :80
Mẹo chuyên nghiệp cho tương lai
- Gỡ cài đặt Apache: Nếu bạn không cần nó,
sudo apt purge apache2sẽ ngăn nó tự động khởi động lại. - Kiểm tra Docker: Nếu bạn sử dụng Docker, hãy kiểm tra
docker ps. Một container được ánh xạ với-p 80:8080sẽ chặn Nginx của máy chủ. - Tự động hóa kiểm tra: Đừng bao giờ khởi động lại Nginx mà không chạy
nginx -ttrước. Nó giúp bạn tránh được thời gian ngừng hoạt động (downtime) do các lỗi đánh máy đơn giản.

