在没有sudo的情况下启动Unicorn

时间:2013-09-24 13:44:47

标签: ruby-on-rails nginx permissions unicorn

我试图在不使用sudo的情况下启动我的独角兽进程。我编写了一个已经符号链接到/etc/init.d/unicorn_arcsite.sh的脚本。

如果我运行service unicorn_arcsite start我的脚本说它开始正常,但我的服务器不处理http请求。看一下独角兽日志,我看到了:

E, [2013-09-24T13:21:39.111308 #16879] ERROR -- : reaped #<Process::Status: pid 26117 exit 1> worker=7
E, [2013-09-24T13:21:39.112981 #26120] ERROR -- : Operation not permitted (Errno::EPERM)
/home/deployer/.rvm/gems/ruby-2.0.0-p195@arcsite_mysql/gems/unicorn-4.6.2/lib/unicorn/worker.rb:83:in `initgroups'
/home/deployer/.rvm/gems/ruby-2.0.0-p195@arcsite_mysql/gems/unicorn-4.6.2/lib/unicorn/worker.rb:83:in `user'
/home/deployer/.rvm/gems/ruby-2.0.0-p195@arcsite_mysql/gems/unicorn-4.6.2/lib/unicorn/http_server.rb:592:in `init_worker_process'
/home/deployer/.rvm/gems/ruby-2.0.0-p195@arcsite_mysql/gems/unicorn-4.6.2/lib/unicorn/http_server.rb:615:in `worker_loop'
/home/deployer/.rvm/gems/ruby-2.0.0-p195@arcsite_mysql/gems/unicorn-4.6.2/lib/unicorn/http_server.rb:500:in `spawn_missing_workers'
/home/deployer/.rvm/gems/ruby-2.0.0-p195@arcsite_mysql/gems/unicorn-4.6.2/lib/unicorn/http_server.rb:511:in `maintain_worker_count'
/home/deployer/.rvm/gems/ruby-2.0.0-p195@arcsite_mysql/gems/unicorn-4.6.2/lib/unicorn/http_server.rb:277:in `join'
/home/deployer/.rvm/gems/ruby-2.0.0-p195@arcsite_mysql/gems/unicorn-4.6.2/bin/unicorn:126:in `<top (required)>'
/home/deployer/.rvm/gems/ruby-2.0.0-p195@arcsite_mysql/bin/unicorn:23:in `load'
/home/deployer/.rvm/gems/ruby-2.0.0-p195@arcsite_mysql/bin/unicorn:23:in `<main>'

正常运行sudo service unicorn_arcsite start

我正在运行nginx,nginx和unicorn通过/tmp/unicorn.arcsite.sock的套接字进行通信。

权限

deployer@arcsite:~/apps/arcsite/current$ service unicorn_arcsite start
/home/deployer/apps/arcsite/current: 
Starting - OK

deployer@arcsite:~/apps/arcsite/current$ ls -ld /tmp/unicorn.arcsite.sock 
srwxrwxrwx 1 deployer sudo 0 Sep 24 13:50 /tmp/unicorn.arcsite.sock

deployer@arcsite:~/apps/arcsite/current$ ls -l tmp/pids/unicorn.pid 
-rw-r--r-- 1 deployer sudo 6 Sep 24 13:50 tmp/pids/unicorn.pid

deployer@arcsite:~/apps/arcsite/current$ id
uid=1000(deployer) gid=27(sudo) groups=27(sudo)

文件

unicorn.rb

# RAILS_ROOT/config/unicorn.rb
# Search for "# SET ME!" and replace these with your own settings!.

# Set environment to development unless something else is specified
env = ENV["RAILS_ENV"] || "development"
ROOT = "<app_root>"


ENV['BUNDLE_GEMFILE'] = File.expand_path('../Gemfile', File.dirname(__FILE__))
require 'bundler/setup'

pid "#{ROOT}/tmp/pids/unicorn.pid"

# See http://unicorn.bogomips.org/Unicorn/Configurator.html for complete
# documentation.
worker_processes 10 # SET ME!

# listen on both a Unix domain socket and a TCP port,
# we use a shorter backlog for quicker failover when busy
listen "/tmp/unicorn.arcsite.sock", :backlog => 1024 # SET ME!

# Preload our app for more speed
preload_app true

GC.respond_to?(:copy_on_write_friendly=) and
    GC.copy_on_write_friendly = true

# nuke workers after 30 seconds instead of 60 seconds (the default)
timeout 30

# Production specific settings
if env == "production"
  # Help ensure your application will always spawn in the symlinked
  # "current" directory that Capistrano sets up.
  working_directory ROOT

  # feel free to point this anywhere accessible on the filesystem
  user 'deployer', 'staff'
  shared_path = "<shared_path>"

  stderr_path "#{shared_path}/log/unicorn.log"
  stdout_path "#{shared_path}/log/unicorn.log"
end

before_fork do |server, worker|
  # the following is highly recomended for Rails + "preload_app true"
  # as there's no need for the master process to hold a connection
  if defined?(ActiveRecord::Base)
    ActiveRecord::Base.connection.disconnect!
  end

  # Before forking, kill the master process that belongs to the .oldbin PID.
  # This enables 0 downtime deploys.
  old_pid = "#{ROOT}/tmp/pids/unicorn.pid.oldbin"
  if File.exists?(old_pid) && server.pid != old_pid
    begin
      Process.kill("QUIT", File.read(old_pid).to_i)
    rescue Errno::ENOENT, Errno::ESRCH
      # someone else did our job for us
    end
  end
end

after_fork do |server, worker|
  # the following is *required* for Rails + "preload_app true",
  if defined?(ActiveRecord::Base)
    ActiveRecord::Base.establish_connection
  end

  # if preload_app is true, then you may also want to check and
  # restart any other shared sockets/descriptors such as Memcached,
  # and Redis.  TokyoCabinet file handles are safe to reuse
  # between any number of forked children (assuming your kernel
  # correctly implements pread()/pwrite() system calls)
end

1 个答案:

答案 0 :(得分:1)

失败的行是独角兽试图改变群组的行:

if gid && Process.egid != gid
  Process.initgroups(user, gid)
  Process::GID.change_privilege(gid)
end

从配置文件中,我会说“部署者”用户不允许更改为“员工”组。您应该更改unicorn配置中的组或将用户添加到该组。