Posting a completely different solution in case someone has a different problem with the same symptoms. In my case, I was running on RHEL with Security-enhanced Linux enabled.
SELinux can block Nginx from accessing the socket, even if filesystem permissions look correct. To check if SELinux is the culprit, temporarily put it in permissive mode with: sudo set enforce 0
Does it work?
If so, you may want to make an exception to the rule.
Remember to revert! sudo setenforce 1
Red Hat has a tutorial for Creating an SELinux Policy (RHEL docs)
This is a bit of a shortcut—if you've tried to start Nginx and it was denied access to the Gunicorn socket, then the denial would be logged in the audit logs. You can use these logs to generate a custom SELinux policy module:
sudo grep gunicorn /var/log/audit/audit.log | sudo audit2allow -M nginx_gunicorn
Looking at the context of the socket, ls -lZ /run/gunicorn.sock
I'm seeing:
system_u:object_r:var_run_t:s0
And for nginx, ps -eZ | grep nginx
:
system_u:system_r:httpd_t:s0
Noting var_run_t and httpd_t in the contexts.
cat nginx_gunicorn.te
Shows the policy, and it should probably have something about allowing the two contexts to interact.
allow httpd_t var_run_t:sock_file write;
While saying a little prayer to the SELinux guardians, you may try enabling the policy.
sudo semodule -i nginx_gunicorn.pp
sudo systemctl restart nginx
**If this doesn't work, you might try a variation of the Holy Grep Incantation on audit log searching for nginx. First, disable the policy you added, then create and enable again.
sudo semodule -r nginx_gunicorn
sudo grep nginx /var/log/audit/audit.log | sudo audit2allow -M nginx_gunicorn
sudo semodule -i nginx_gunicorn.pp
Godspeed.