Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I've created an nginx/unicorn/capistrato setup on Ubuntu (Amazon EC2) by following mostly this guide. I guess everything is set up like it should but when I start Unicorn I get (a LOT of) this error in the log:

E, [2012-09-08T08:57:20.658092 #12356] ERROR -- : Operation not permitted (Errno::EPERM)
/home/deployer/apps/bridgekalenderen.no/shared/bundle/ruby/1.9.1/gems/unicorn-4.3.1/lib/unicorn/worker.rb:82:in `initgroups'

I see it's related to the user's permissions but I just can't figure out what I've left out. The server starts up nicely if I start it with sudo (or, rvmsudo, really).

The user has sudo capabilities, I have chmod'ed the app several times so the file permissions there should be ok. The unicorn socket in /tmp is owned by the deployer user, so that shouldn't be the problem either.

Does anybody have a clue where to look?

UPDATE:

After some digging I found out that it boils down to a call to Process.initgroups which throws EPERM. I've verified this in irb. I can't figure out what causes the error. The user can read /etc/group.

share|improve this question
add comment

3 Answers

If I understand you well, you are trying to start a service without sudo under normal user. This will not work and will give your errors like the ones you received Operation not permitted. This is true in most (if not all) cases because any service will require one or more of the following to do its job:

  1. Binding/listening on ports < 1024.
  2. Reading file(s) not readable by non-root.
  3. Writing file(s) not writeable by non-root.
  4. and possibly more (I can not recall).
share|improve this answer
add comment
up vote 1 down vote accepted

I finally figured it out. The problem was that the deployer user's primary group was wrong. It should be 'staff' but was 'deployer' instead. This means that unicorn tries to hand over the ownership of new worker processes to the group it's supposed to use, but only root can do that.

Just in case anybody else needs to know, I changed the primary group by editing /etc/passwd like this:

deployer:x:1002:50:,,,:/home/deployer:/bin/bash

'50' is the gid of 'staff'. It was 1002 to begin with. To get the gid of the 'staff' group, do:

cat /etc/group | grep staff

It will say something along the lines of:

staff:x:50:<comma separated list of users in this group>

The gid is the number after 'x'.

share|improve this answer
add comment

I've encountered the same issue. What ended up working for me was setting the following in my unicorn config in the after_fork do |server, worker| block: (it's from the github unicorn config)

  begin
    uid, gid = Process.euid, Process.egid
    user, group = 'deployer', 'staff'
    target_uid = Etc.getpwnam(user).uid
    target_gid = Etc.getgrnam(group).gid
    worker.tmp.chown(target_uid, target_gid)
    if uid != target_uid || gid != target_gid
      Process.initgroups(user, target_gid)
      Process::GID.change_privilege(target_gid)
      Process::UID.change_privilege(target_uid)
    end
  rescue => e
    if RAILS_ENV == 'development'
      STDERR.puts "couldn't change user, oh well"
    else
      raise e
    end
  end
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.