Brandon Pancost
Brandon Pancost

Reputation: 26

Setting up Unicorn for multi-user Capistrano deployment

I have been having some trouble with migrating a capistrano deployment of our rails app to make it so that multiple users can deploy. Originally we had a the socket for our unicorn server under /tmp owned by the user who would do the deploy. This doesn't work with multiple users because they would not have the permissions to modify the file.

We tried a second approach where we put the socket file under the app in its tmp directory. After each deploy, we reset the ownership of the socket file to a deployer's group which is shared between the users. This would work for the first deploy by a user, but not if the same user made a second deploy in a row. If a different user deploys, it works fine.

Basically we ended up with a deployment system where each person can deploy only once in a row before having to ask another person to deploy once in between. It looks like on the second and further deploys, the unicorn processes are not being restarted properly. On the first deploy the unicorn log for the successful deploy shows this:

INFO -- : Refreshing Gem list
INFO -- : listening on addr=/var/www/dashboard/current/tmp/dashboard.socket fd=11
INFO -- : worker=0 ready
INFO -- : worker=1 ready
INFO -- : worker=2 ready
INFO -- : master process ready
INFO -- : worker=3 ready

On the second deploy the failed log looks like this:

INFO -- : executing ["/var/www/dashboard/shared/bundle/ruby/2.1.0/bin/unicorn", "-c", "/var/www/dashboard/current/config/unicorn/production.rb", "-E      ", "deployment", "-D", {11=>#<Kgio::UNIXServer:/var/www/dashboard/current/tmp/dashboard.socket>}] (in /var/www/dashboard/releases/20160405234438)
INFO -- : forked child re-executing...
INFO -- : inherited addr=/var/www/dashboard/current/tmp/dashboard.socket fd=11
INFO -- : Refreshing Gem list
INFO -- : reaped #<Process::Status: pid 22939 exit 0> worker=0
INFO -- : reaped #<Process::Status: pid 22942 exit 0> worker=1
INFO -- : reaped #<Process::Status: pid 22945 exit 0> worker=2
INFO -- : reaped #<Process::Status: pid 22948 exit 0> worker=3
INFO -- : master complete
INFO -- : worker=0 ready
INFO -- : worker=1 ready
INFO -- : worker=2 ready
INFO -- : master process ready
INFO -- : worker=3 ready

The gem we are using for our unicorn deployment is capistrano-unicorn. We are using ruby 2.1.5, capistrano 2.15.7, and unicorn 5.0.1.

Upvotes: 1

Views: 99

Answers (1)

Matouš Bor&#225;k
Matouš Bor&#225;k

Reputation: 15954

You should run unicorn under a separate user, not related to individual developers, such as www. Then the unicorn socket may be elsewhere, e.g. in /tmp. Use the unicorn_user option (see the gem readme) to make Capistrano reload or restart the unicorn server under the given user.

You will also have to set up a sudo rule for your developers group so that they can run commands as the www user, without giving password. Add something like this to /etc/sudoers file:

%developers ALL=(www) NOPASSWD: ALL

Warning: this allows any user in the developers group to run any command as the www user without giving password! A cleaner and more secure approach would be to allow only the commands for starting unicorn and sending it the signals for reloading / stopping etc.

Upvotes: 1

Related Questions