nginx returns 404 on a site that is clearly built, the /var/www traverse trap

The problem. A site is built, the files are in place, the nginx config points at the correct public folder, and nginx still returns 404. Everything below the docroot is world readable, so it makes no sense, until you look at the directories above it.

The fix.

nginx runs as the www-data user. To serve a file, www-data has to traverse every directory in the path, all the way down. If any directory along the way is drwx------ (700), or otherwise blocks others, www-data can not pass through it, and you get a 404 even though the file itself is perfectly readable.

Check the whole path at once:

namei -l /var/www/html/yoursite/public/index.html

Look for any component owned by your user with no execute bit for others. It is very often /var/www itself, sitting at 700. Grant traverse, which is the execute bit for others, not read:

chmod o+x /var/www

If your user owns /var/www, you can do this without sudo. www-data only needs to pass through the directory, not list it, so o+x is the minimal and correct fix. Nothing to reload, the next request just works.