Update 7/1/2014: I’ve had to revise this after being unable to get it work on a recent project.
At work we’ve been rolling out PHP-FPM to more and more of our clients’ servers, which has been great for performance and keeping server loads down. The only issue we’ve had (beyond some initial configuration) was related to our deployments: many of our projects, especially our web applications, are deployed through Capistrano, a Ruby-based task runner that’s extremely popular among the Ruby on Rails crowd. While Capistrano let’s us reduce deployments to running cap production deploy
, PHP-FPM typically needs to be restarted before it will start using the new code.
Having to manually SSH into a server to restart PHP-FPM after a deployment takes some of the sexy out of one-line deployments, so we sought to find a better way. The goal: be able to restart PHP-FPM (sudo service php5-fpm restart
) from within a Capistrano task without being prompted for passwords (we use Public-Key authentication) or having to manually SSH in to restart the server.
The first thought was to deploy the application as root (the developer who suggested this was promptly handed a hastily-fashioned cone of shame); running the application as root would require a) users to be able to SSH into the server as root (which could be catastrophic if one of those private keys fell into the wrong hands) and b) absolute confidence that the application would never be compromised as the app itself would have full run of the server. It was clear that running the application as root wasn’t an option, but we’d need to find some way to execute a privileged command.
It was at this point we learned that root access can be granted to a user for a limited subset of commands. Finally, the answer to our prayers: a way for our unprivileged user (on this server, “deploy”) to restart PHP-FPM and nothing else. Score!
To set it up on your server, run visudo
as root and add the following to it under the “User privilege specification” comment:
1 |
deploy ALL=NOPASSWD: /usr/sbin/service php5-fpm restart |
This tells your server that the “deploy” user should be able to run sudo /etc/init.d/php5-fpm
(recent Debian-based Linux releases alias this to service php5-fpm
) without being prompted for a password. Now, from our Capistrano configuration, we can execute the following:
1 |
run "sudo /usr/sbin/service php5-fpm restart" |
Do you see what we did there? We just brought sexy back to scripted deployments for apps running under PHP-FPM. This same bit of knowledge can also enable you to deal with Apache, Nginx, or any other service that you need to without opening the floodgates of your application user having unfettered root access.
kinaz
Hey,
you saved my day!
Thanks
David
Why does PHP-FPM have to be restarted? I’m having similar issues. On one setup I’m using PHP-FPM, and on another mod_fcgi. In both cases, deployments are unreliable. Sometimes the new code gets picked up right away, other times it can take several minutes. For my FPM setup, I can try restarting as suggested here, but I can’t do the same with fcgi (shared hosting). Opcode caching is disabled on one server, and the other doesn’t have any installed. So I’m assuming the problem is related to the php worker pool.
Bill (@bmitch2112)
This is great. Thanks
Pavel Dubinin
Also note that order is important in sudoers config!
When multiple entries match for a user, they are applied in order. Where there are multiple matches, the last match is used (which is not necessarily the most specific match).
http://askubuntu.com/a/100112/286499
Mark Railton
Thanks Steve, this is exactly what I needed.