Nginx 502 Bad Gateway After Laravel Deploy – Full Debug and Fix Checklist
You deploy a fresh Laravel app, point Nginx to public/index.php, reload the browser, and instead of your homepage you get: 502 Bad Gateway nginx This means Nginx could not talk properly to the backend, usually PHP-FPM. The good part is that the problem is almost always in a few predictable places.
Here is a practical checklist you can follow from top to bottom until the 502 is gone.
1. Confirm PHP-FPM is running
First, make sure the PHP engine is alive.
On Ubuntu or Debian:
sudo systemctl status php8.3-fpm
On CentOS or similar:
sudo systemctl status php-fpm
If it is stopped, start or restart it:
sudo systemctl restart php8.3-fpm
If it fails immediately, check the PHP-FPM error log (often in /var/log/php8.3-fpm.log).
2. Check Nginx upstream configuration
Open your Nginx site file, often something like:
/etc/nginx/sites-available/your-site.conf
Common fastcgi block for Laravel:
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_index index.php;
}
Typical mistakes:
- Wrong socket path. For example using
php8.2-fpm.sockwhile onlyphp8.3-fpm.sockexists. - Using
127.0.0.1:9000but PHP-FPM is listening on a Unix socket, or vice versa.
You can list available sockets:
ls /run/php/
Match fastcgi_pass to an existing .sock or to the TCP port defined in /etc/php/8.3/fpm/pool.d/www.conf.
After editing:
sudo nginx -t
sudo systemctl reload nginx
3. Make sure Nginx points to Laravel’s public folder
The root must be the public directory, not the project root.
server {
server_name example.com;
root /var/www/laravel-app/public;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_index index.php;
}
}
If the root points to /var/www/laravel-app directly, Nginx might try to send the wrong file to PHP-FPM and trigger a 502.
4. Fix permissions for storage and cache
If PHP cannot write to storage or cache, Laravel can crash before sending a response.
From your project root:
sudo chown -R www-data:www-data storage bootstrap/cache
sudo find storage bootstrap/cache -type d -exec chmod 755 {} \;
sudo find storage bootstrap/cache -type f -exec chmod 644 {} \;
Replace www-data with your web server user if different.
5. Check Laravel log and PHP-FPM log
A 502 at the browser does not show the real error. The actual exception often exists in storage/logs/laravel.log.
tail -f storage/logs/laravel.log
Refresh the site and watch the log output. You might see issues like:
- Wrong database credentials
- Missing
.envfile - Composer autoload errors
Also inspect the PHP-FPM log:
sudo tail -f /var/log/php8.3-fpm.log
Errors like “child exited on signal 11” or “PHP Fatal error” will appear there.
6. Verify .env and application key
On new deployments it is easy to forget the .env file or the app key.
Make sure:
.envexists on the server.APP_KEYis set.
If not, copy .env.example to .env, adjust database and other settings, then run:
php artisan key:generate
php artisan config:clear
7. Run Composer and Laravel optimization commands
On the server, from the project root:
composer install --no-dev --optimize-autoloader
php artisan config:clear
php artisan cache:clear
php artisan route:clear
php artisan view:clear
If the vendor folder is incomplete or config cache is stale, PHP may crash and cause a 502.
8. Increase fastcgi and PHP-FPM timeouts if needed
If a script takes too long, Nginx may give up and show a 502.
In your Nginx PHP block, you can try:
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_read_timeout 120s;
}
In PHP-FPM pool config (/etc/php/8.3/fpm/pool.d/www.conf):
request_terminate_timeout = 120
Restart services after changes:
sudo systemctl restart php8.3-fpm
sudo systemctl reload nginx
Only increase timeouts if you really have heavy tasks. For normal pages, keep them modest.
9. Check for missing index.php or wrong file ownership
Confirm public/index.php exists and is readable.
ls -l public/index.php
Permissions should look roughly like:
-rw-r--r-- 1 www-data www-data ...
If the file belongs to root and is not readable by the web user, you may also see 502 errors. Fix with:
sudo chown -R www-data:www-data /var/www/laravel-app
10. Quick 502 debug checklist
When you see “502 Bad Gateway” after a Laravel deploy:
- Check that PHP-FPM is running and restart it.
- Confirm
fastcgi_passin Nginx matches the real socket or port. - Ensure
rootis set toproject/public. - Fix permissions on
storageandbootstrap/cache. - Read
storage/logs/laravel.logand the PHP-FPM error log. - Verify
.envandAPP_KEY, then clear config and caches. - Install Composer dependencies with
composer install. - Adjust Nginx and PHP-FPM timeouts only if necessary.
Work through this list calmly and you will almost always find the reason behind the 502 and get your Laravel app serving responses again.