Nginx and PHP as Different Users (Pooling)
So, after having installed a few WordPress sites on my server (namely this one), I ran into some permissions errors. I couldn’t get plugins nor any updates to install.
The problem first appeared simply as a prompt to enter FTP credentials. That was bizarre, so I hunted to find why that was. I realized it was a permissions issue by reading this page (among others).
I scoured the Internet for answers (in other words, I tried a lot of different search terms in Google) for a way to make Nginx, the webserver software I used, to run as the proper user. I’d setup different users for different websites, so just changing the webserver’s default user/group wasn’t the answer.
My first solution, albeit an ugly one, was to give everybody read+write+execute permissions on my WP folders. That was an ugly kludge, but it worked. And so it sat for some time.
Then I finally found how. Through some bit of serendipity, I found an article on Apache and suExec. I changed the term to Nginx with suExec, and found the answer… sort of.
Nginx, PHP-FPM, and Pooling
So the key was the “pooling” part of PHP-FPM that I’d basically ignored. I had read the configuration file, but didn’t really understand it.
But after reading this article about pooling with Nginx and PHP-FPM, I found the answer.
So PHP-FPM can be configured to run different pools. Basically, that means that there are multiple main processes for PHP, and they can run as different users.
Easy. Added a new pool, changed it’s name and the user, and the new process (well, processes) appeared, with the correct user. But how could I attach that to my website, so it ran as the correct user (instead of www-data)?
It’s All In The Socket
The bit of magic that makes Nginx hand off the PHP work to the correct pool is the socket. The new pool needed to have a unique socket, then the affected websites needed to be reconfigured to use the socket corresponding to the appropriate pool.
I went back and changed my new pool to have a unique socket name, then restarted the php5-fpm process. I then went and changed my website’s configuration file to use the corresponding socket.
Before restarting Nginx, I changed the permissions on my website’s folder to no longer be world readable/writable. Then I attempted to delete an old plugin: as expected, I got a permissions error. Restarted Nginx, then tried again, and it worked. Woot!