Fix 504 Gateway Timeout Error on WordPress (Nginx + PHP 8.3-FPM) – Step-by-Step Guide

Lỗi 504 Gateway Time-out (nginx) với WordPress/PHP-FPM thường do PHP-FPM (hoặc backend khác) không kịp trả lời trong thời gian Nginx chờ. Dưới đây là playbook xử lý nhanh, theo thứ tự ưu tiên — làm lần lượt và test lại sau mỗi bước.

1) Kiểm tra log để biết nguyên nhân

# Nginx error log (thường có dòng upstream timed out)
sudo tail -n 200 /var/log/nginx/error.log

# PHP-FPM 8.3 logs
sudo journalctl -u php8.3-fpm -n 200 --no-pager
sudo tail -n 200 /var/log/php8.3-fpm.log 2>/dev/null || true

# Slowlog (nếu đã bật, xem bước 4C để bật)
sudo grep -R "pool www" -n /var/log/php*/ | tail -n 50

2) Xác nhận Nginx → PHP-FPM đúng “địa chỉ”

Mở file server block của site, kiểm tra fastcgi_pass khớp với PHP-FPM:

  • Dùng socket (khuyến nghị): fastcgi_pass unix:/run/php/php8.3-fpm.sock;
  • Hoặc TCP: fastcgi_pass 127.0.0.1:9000;

Ví dụ cấu hình WordPress tối thiểu (server block):

location ~ \.php$ {
    include snippets/fastcgi-php.conf;  # hoặc fastcgi_params chuẩn của distro
    fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    fastcgi_read_timeout 180s;          # tăng thời gian chờ
    fastcgi_buffers 16 16k;
    fastcgi_buffer_size 32k;
}

Rồi reload:

sudo nginx -t && sudo systemctl reload nginx

3) Tăng timeout phía Nginx (tránh 504 do tác vụ nặng)

Trong http hoặc server:

send_timeout 120s;
proxy_read_timeout 180s;      # nếu có proxy tới backend khác
fastcgi_read_timeout 180s;    # quan trọng cho PHP

Reload Nginx:

sudo nginx -t && sudo systemctl reload nginx

4) Tối ưu & giới hạn PHP-FPM (điểm hay gây 504)

A) Bật giới hạn thời gian xử lý (để treo không kéo dài):

# /etc/php/8.3/fpm/pool.d/www.conf
request_terminate_timeout = 120s

B) Điều chỉnh process manager cho phù hợp RAM:

; /etc/php/8.3/fpm/pool.d/www.conf
pm = dynamic
pm.max_children = 20         ; tính theo RAM, ví dụ bên dưới
pm.start_servers = 4
pm.min_spare_servers = 4
pm.max_spare_servers = 8
pm.max_requests = 500

Cách ước lượng pm.max_children:

max_children ≈ (RAM_cho_PHP_FPM_MB) / (bộ nhớ trung bình mỗi PHP process)

Ví dụ RAM ~1500MB cho PHP-FPM, mỗi process ~60–80MB ⇒ 1500/70 ≈ 21 → đặt 20.

C) Bật slowlog để “bắt” đoạn PHP nào chạy lâu:

; /etc/php/8.3/fpm/pool.d/www.conf
slowlog = /var/log/php8.3-fpm.slow.log
request_slowlog_timeout = 5s

Sau khi sửa:

sudo systemctl restart php8.3-fpm

Rồi theo dõi:

sudo tail -f /var/log/php8.3-fpm.slow.log

D) Tăng giới hạn thực thi PHP (nếu thực sự cần):

; /etc/php/8.3/fpm/php.ini
max_execution_time = 120
memory_limit = 512M         ; hoặc cao hơn nếu xử lý media lớn

Restart FPM: sudo systemctl restart php8.3-fpm

5) Kiểm tra “nút thắt” WordPress

  • Vô hiệu hoá toàn bộ plugin để loại trừ (dùng WP-CLI): cd /var/www/html # tới root WP wp plugin deactivate --all wp theme activate twentytwentyfour Nếu hết 504 → bật lại từng nhóm plugin để tìm thủ phạm.
  • Tắt/mặc định cron WP nếu cron web gây kẹt:
    • Thêm vào wp-config.php: define('DISABLE_WP_CRON', true);
    • Tạo cron hệ thống 5 phút/lần: */5 * * * * www-data /usr/bin/php8.3 /var/www/html/wp-cron.php > /dev/null 2>&1
  • Bật object cache & page cache:
    • Redis Object Cache plugin + Redis server (giảm tải DB).
    • Page cache (plugin) hoặc fastcgi_cache của Nginx (xem #8).

6) Kiểm tra MySQL (DB chậm cũng gây 504)

  • Xem slow query log: SET GLOBAL slow_query_log = 'ON'; SET GLOBAL long_query_time = 1;
  • Theo dõi tài nguyên: top -c # CPU/RAM vmstat 1 # memory/swap iostat -xz 1 # I/O
  • Kiểm tra kết nối DB có bị nghẽn do max_connections hay lock.

7) Bài test nhanh để phân loại lỗi timeout

Tạo file /var/www/html/test-sleep.php:

<?php
sleep(70);
echo "done";
  • Nếu gọi curl -I http://domain/test-sleep.php mà 504 khoảng ~60s → tăng fastcgi_read_timeout (Nginx).
  • Nếu vẫn 504 dù đã tăng → check request_terminate_timeout (FPM) hoặc max_execution_time.

8) (Tuỳ chọn) Thêm FastCGI Cache cho trang công khai (rất hiệu quả)

Trong http {}:

fastcgi_cache_path /var/cache/nginx/fastcgi levels=1:2 keys_zone=phpcache:100m inactive=60m max_size=2g;
map $request_method $skip_cache {
    default 0;
    POST 1;
    PUT 1;
    DELETE 1;
    PATCH 1;
}

Trong server { location ~ \.php$ { ... } }:

fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;
fastcgi_cache phpcache;
fastcgi_cache_valid 200 301 302 60m;
add_header X-FastCGI-Cache $upstream_cache_status;

9) Những lỗi cấu hình phổ biến gây 504

  • fastcgi_pass trỏ nhầm socket (ví dụ trỏ 8.2 trong khi đang chạy 8.3).
  • PHP-FPM pool down/crash: kiểm tra systemctl status php8.3-fpm.
  • Thiếu index.php trong index directive: index index.php index.html;
  • Rule try_files sai khiến .php không đi vào location ~ \.php$: location / { try_files $uri $uri/ /index.php?$args; }

Tóm tắt từng bước debug:

  1. Kiểm tra log Nginx & PHP-FPM (#1).
  2. Xác nhận fastcgi_pass đúng và tăng fastcgi_read_timeout (#2–#3).
  3. Điều chỉnh FPM pool, bật slowlog (#4).
  4. Test test-sleep.php để xác định phía nào timeout (#7).
  5. Tạm tắt plugin/theme nặng, chuyển cron sang hệ thống (#5).
  6. Kiểm tra DB chậm, tối ưu truy vấn hoặc bổ sung Redis cache (#6).
  7. (Nếu site public lớn) Bật FastCGI cache (#8).

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *