How to Fix Nginx 502 Bad Gateway on DigitalOcean Droplet
The Root Cause
Nginx 502 Bad Gateway on DigitalOcean Droplets frequently indicates that Nginx cannot reach its configured upstream application server, most commonly PHP-FPM, due to it being overloaded, crashed, or improperly configured. This often stems from insufficient memory or process limits allocated to the application server for the Droplet’s available resources, or a mismatch in socket paths between Nginx and PHP-FPM.
Quick Fix (CLI)
# 1. Check the status of your PHP-FPM service (adjust 'php7.4-fpm' to your specific PHP version, e.g., 'php8.1-fpm' or 'php-fpm')
sudo systemctl status php7.4-fpm
# 2. If PHP-FPM is inactive, failing, or appears overloaded, restart it
sudo systemctl restart php7.4-fpm
# 3. Restart Nginx to ensure it re-establishes connections to the upstream
sudo systemctl restart nginx
# 4. Review Nginx error logs for specific clues if the issue persists
sudo tail -n 50 /var/log/nginx/error.log
Configuration Check
1. Nginx Configuration
Edit your Nginx site configuration file. This is typically located at /etc/nginx/sites-available/your_domain.conf or /etc/nginx/sites-available/default.
Within the location ~ \.php$ block, ensure the fastcgi_pass directive correctly points to your PHP-FPM socket or TCP address:
# File: /etc/nginx/sites-available/your_domain.conf (or default)
server {
# ... other configurations ...
location ~ \.php$ {
include snippets/fastcgi-php.conf;
# Ensure this matches your PHP-FPM listen directive
# For Unix socket (recommended):
fastcgi_pass unix:/run/php/php7.4-fpm.sock; # Adjust 'php7.4-fpm.sock' to your PHP version
# OR, for TCP socket:
# fastcgi_pass 127.0.0.1:9000;
}
# ... other configurations ...
}
2. PHP-FPM Configuration
Edit your PHP-FPM pool configuration file. This is typically located at /etc/php/7.4/fpm/pool.d/www.conf (adjust 7.4 to your PHP version).
Ensure the listen directive matches the fastcgi_pass setting in your Nginx configuration. Also, adjust pm.* directives and memory_limit to prevent resource exhaustion, especially on smaller Droplets.
; File: /etc/php/7.4/fpm/pool.d/www.conf
; Ensure this matches Nginx's fastcgi_pass directive
listen = /run/php/php7.4-fpm.sock
; OR
; listen = 127.0.0.1:9000
; Adjust these values based on your Droplet's RAM and application needs
; For a 1GB Droplet, start with lower values and scale up if needed.
; pm = dynamic is common, static if very high traffic and consistent memory use.
pm.max_children = 20 ; Total number of PHP-FPM child processes. (e.g., RAM / average_php_process_size)
pm.start_servers = 5 ; Number of children created on startup
pm.min_spare_servers = 5 ; Minimum number of idle server processes
pm.max_spare_servers = 15 ; Maximum number of idle server processes
pm.max_requests = 500 ; Number of requests a child process will serve before recycling
; File: /etc/php/7.4/fpm/php.ini (adjust '7.4' to your PHP version)
; Increase if scripts run out of memory (check PHP-FPM logs)
memory_limit = 256M ; Example, increase from default 128M
After making configuration changes:
sudo nginx -t # Test Nginx configuration for syntax errors
sudo systemctl reload nginx # Apply Nginx changes without dropping connections
sudo systemctl restart php7.4-fpm # Restart PHP-FPM to apply its changes
Verification
curl -I http://your_domain_or_droplet_ip