Vấn đềBạn mở trang Tools > Site Health và thấy một cảnh báo màu đỏ rực. WordPress báo cáo rằng REST API hoặc loopback request đã thất bại. Khi kiểm tra nhật ký (logs), bạn thấy lỗi cụ thể này:
cURL error 7: Failed to connect to localhost port 80: Connection refused
Đây không chỉ là vấn đề về giao diện. Khi cURL gặp lỗi, trang web của bạn sẽ mất khả năng thực hiện các tác vụ nền thiết yếu. Nó không thể kiểm tra cập nhật plugin, không thể kích hoạt các bài viết đã lên lịch (wp-cron), và thậm chí có thể làm hỏng trình soạn thảo Gutenberg. Về cơ bản, máy chủ đang cố gắng tự kết nối với chính nó, nhưng kết nối đó bị từ chối.
Tại sao điều này lại xảy ra?Một "loopback request" xảy ra khi WordPress gửi một yêu cầu HTTP ngược lại máy chủ của chính nó. Nếu bạn nhận được thông báo "Connection refused", nguyên nhân thường nằm ở một trong bốn nút thắt kỹ thuật sau:
- Sai lệch DNS: Máy chủ cố gắng phân giải
localhosthoặc tên miền của bạn thành 127.0.0.1, nhưng dịch vụ web của bạn không lắng nghe trên IP cụ thể đó.- Tường lửa nghiêm ngặt: Các công cụ bảo mật như UFW hoặc IPTables đang chặn lưu lượng truy cập trên giao diện loopback cục bộ (lo).- Cấu hình Web Server: Nginx hoặc Apache được cấu hình để chỉ lắng nghe trên IP công cộng của bạn, bỏ qua các yêu cầu được gửi đến 127.0.0.1.- Cách ly trong Docker: Bên trong một container,localhostám chỉ chính container đó chứ không phải máy chủ vật lý đang chạy web server của bạn.## Bước 1: Xác minh kết nối qua CLIBắt đầu bằng cách xác nhận lỗi từ phía máy chủ. SSH vào máy của bạn và chạy lệnh sau:
curl -I http://localhost:80
Nếu kết quả trả về là Connection refused, vấn đề nằm ở hệ điều hành hoặc cấu hình mạng của bạn. Tuy nhiên, nếu bạn thấy phản hồi 200 OK ở đây nhưng vẫn thấy lỗi trong WordPress, vấn đề có thể liên quan đến PHP-FPM hoặc các cài đặt WordPress cụ thể.
Bước 2: Cập nhật tệp /etc/hostsMáy chủ của bạn cần biết chính xác nơi gửi các yêu cầu cục bộ. Thường thì nó sẽ bị nhầm lẫn khi cố gắng phân giải tên miền của bạn. Hãy mở tệp hosts với quyền sudo:
sudo nano /etc/hosts
Đảm bảo tên miền của bạn được ánh xạ tới IP cục bộ. Nếu trang web của bạn là example.com, tệp của bạn sẽ trông như thế này:
127.0.0.1 localhost example.com
::1 localhost ip6-localhost ip6-loopback
Lưu tệp và thoát. Điều này buộc máy chủ phải tìm kiếm nội bộ thay vì cố gắng định tuyến yêu cầu ra ngoài internet công cộng rồi quay ngược trở lại.
Bước 3: Kiểm tra các chỉ thị 'Listen' của Web ServerNếu máy chủ web của bạn chỉ lắng nghe trên IP công cộng (ví dụ: 123.123.123.123), bất kỳ yêu cầu nào gửi đến 127.0.0.1 sẽ bị bỏ qua.
Đối với Nginx:Kiểm tra cấu hình trang web của bạn trong /etc/nginx/sites-available/. Tìm chỉ thị listen:
server {
listen 80; # Lắng nghe trên tất cả các giao diện
# Hoặc thêm cụ thể:
listen 127.0.0.1:80;
server_name localhost example.com;
}
Đối với Apache:Kiểm tra tệp ports.conf hoặc khối VirtualHost. Đảm bảo bạn không giới hạn giao diện:
Listen 80
Sau khi thực hiện thay đổi, hãy khởi động lại dịch vụ: sudo systemctl restart nginx.
Bước 4: Điều chỉnh quy tắc tường lửaTường lửa thường chặn giao diện loopback cục bộ theo mặc định trên các máy chủ được bảo mật cao. Nếu bạn sử dụng UFW trên Ubuntu, hãy cho phép lưu lượng truy cập trên giao diện 'lo' bằng các lệnh sau:
sudo ufw allow in on lo
sudo ufw allow out on lo
Đối với người dùng Firewalld trên CentOS hoặc RHEL, hãy thêm giao diện vào vùng tin cậy (trusted zone):
sudo firewall-cmd --permanent --zone=trusted --add-interface=lo
sudo firewall-cmd --reload
Bước 5: Giải pháp cho DockerTrong Docker, localhost bị cách ly trong container. Nếu WordPress nằm trong một container và Nginx nằm trong một container khác, chúng không thể nhìn thấy nhau qua localhost. Cách khắc phục dễ nhất là sử dụng tên dịch vụ (service name) từ tệp docker-compose.yml của bạn.
Nếu bạn không thể thay đổi URL, hãy thêm một mục extra_hosts vào dịch vụ WordPress của bạn. Điều này ánh xạ tên miền của bạn tới IP của Docker bridge (thường là 172.17.0.1):
services:
wordpress:
extra_hosts:
- "example.com:172.17.0.1"
Bước 6: Bỏ qua cài đặt ProxyNếu máy chủ của bạn nằm sau một proxy doanh nghiệp, cURL có thể đang cố gắng định tuyến các yêu cầu cục bộ thông qua proxy đó. Điều này thường dẫn đến hết thời gian chờ (timeout) hoặc bị từ chối. Hãy yêu cầu WordPress bỏ qua proxy cho lưu lượng nội bộ bằng cách thêm dòng này vào tệp wp-config.php của bạn:
define('WP_PROXY_BYPASS_HOSTS', 'localhost, 127.0.0.1, example.com');
Xác minhQuay lại trang Tools > Site Health. Các bài kiểm tra "REST API" và "Loopback request" bây giờ sẽ hiển thị trạng thái "Passed" màu xanh lá cây. Để chắc chắn 100%, bạn có thể chạy một bài kiểm tra nhanh qua WP-CLI:
wp eval "$res = wp_remote_get('http://localhost/wp-json/'); echo is_wp_error($res) ? $res->get_error_message() : 'Connection Successful';"

