私はUbuntu(Amazon EC2)でnginx/Unicorn/capistratoセットアップを作成しましたが、そのほとんどは このガイド です。すべてが正常に設定されていると思いますが、Unicornを起動すると、ログに次のエラーが表示されます(多くの場合)。
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'
ユーザーの権限に関連しているようですが、何を省略したのか理解できません。サーバーをSudo(または、実際にはrvmsudo)で起動すると、サーバーは正常に起動します。
ユーザーはSudo機能を持っています。私はアプリを数回chmodしたので、ファイルのアクセス許可は問題ないはずです。/tmp内のUnicornソケットはデプロイヤーユーザーが所有しているため、これも問題にはなりません。
誰かがどこを見るべきか手がかりを持っていますか?
更新:
少し掘り下げた後、私はそれがEPERMをスローするProcess.initgroups
への呼び出しに要約されることを発見しました。私はこれをirbで確認しました。エラーの原因がわかりません。ユーザーは/etc/group
を読み取ることができます。
私はついにそれを理解しました。問題は、デプロイヤーユーザーのプライマリグループが間違っていたことでした。 'staff'である必要がありますが、代わりに 'deployer'でした。つまり、Unicornは、新しいワーカープロセスの所有権を、使用することになっているグループに引き渡そうとしますが、それを実行できるのはrootだけです。
他の誰かが知る必要がある場合に備えて、次のように/etc/passwd
を編集してプライマリグループを変更しました。
deployer:x:1002:50:,,,:/home/deployer:/bin/bash
「50」は「スタッフ」のギッドです。そもそも1002年でした。 'staff'グループのgidを取得するには、次のようにします。
cat /etc/group | grep staff
それは次の線に沿って何かを言うでしょう:
staff:x:50:<comma separated list of users in this group>
Gidは、「x」の後の番号です。
私があなたをよく理解しているなら、あなたは通常のユーザーの下でSudo
なしでサービスを開始しようとしています。これは機能せず、受け取ったようなエラーが発生します操作は許可されていません。これは、すべてではないにしてもほとんどの場合に当てはまります。これは、サービスがそのジョブを実行するために次の1つ以上を必要とするためです。
私は最近これで男の日を失いました。コンテキストはappsという名前のユーザーでUnicornを実行しようとしていましたが、Errno :: EPERMエラーが私たちを噛み続けました。スタックトレースは次のとおりです。
E, [2018-04-12T20:45:07.277588 #2048] ERROR -- : Operation not permitted (Errno::EPERM)
/apps/cas-seas3/shared/bundle/Ruby/2.2.0/gems/Unicorn-5.4.0/lib/Unicorn/worker.rb:143:in `initgroups'
/apps/cas-seas3/shared/bundle/Ruby/2.2.0/gems/Unicorn-5.4.0/lib/Unicorn/worker.rb:143:in `user'
/apps/cas-seas3/shared/bundle/Ruby/2.2.0/gems/Unicorn-5.4.0/lib/Unicorn/http_server.rb:657:in `init_worker_process'
/apps/cas-seas3/shared/bundle/Ruby/2.2.0/gems/Unicorn-5.4.0/lib/Unicorn/http_server.rb:682:in `worker_loop'
/apps/cas-seas3/shared/bundle/Ruby/2.2.0/gems/Unicorn-5.4.0/lib/Unicorn/http_server.rb:549:in `spawn_missing_workers'
/apps/cas-seas3/shared/bundle/Ruby/2.2.0/gems/Unicorn-5.4.0/lib/Unicorn/http_server.rb:563:in `maintain_worker_count'
/apps/cas-seas3/shared/bundle/Ruby/2.2.0/gems/Unicorn-5.4.0/lib/Unicorn/http_server.rb:293:in `join'
/apps/cas-seas3/shared/bundle/Ruby/2.2.0/gems/Unicorn-5.4.0/bin/Unicorn:126:in `<top (required)>'
/apps/cas-seas3/shared/bundle/Ruby/2.2.0/bin/Unicorn:23:in `load'
/apps/cas-seas3/shared/bundle/Ruby/2.2.0/bin/Unicorn:23:in `<top (required)>'
143行目の周りにprintステートメントを使用してコードベースをインストルメント化すると、次のデバッグ情報が得られました。
user = apps
group=apps
uid=1040
gid=110
whoami=apps
Process.egid = 1001
GidとProcess.egidの間のその不一致により、このコードブロックが作動しました。
if gid && Process.egid != gid
Process.initgroups(user, gid)
Process::GID.change_privilege(gid)
end
それが失敗の原因です。
私はついにそれをGID/EGIDの違いにたどり着きました。問題は、アプリユーザーが別のプライマリグループ(admin)に属していることでした。アプリユーザーをプライマリとしてアプリグループに移動すると、機能しました。これは、ボックスのユーザーアカウントを定義した/ etc/passwdファイルを編集することによって行われました。
これをテストする別の方法は、sgを使用して、次のようなsgコマンドを使用して正しいグループでUnicornを手動で実行することです。
bundle exec sg apps -c Unicorn -c /apps/cas-seas3/current/config/Unicorn.rb -E deployment -D
それが機能することがわかった場合、これはユーザー/グループの設定を調べるための非常に良い兆候です。
Unicornは、ユーザー/グループの設定に非常に敏感で、/ etc/passwdと/ etc/groupをチェックし、このps行を使用して、実行中のUnicornプロセスのUIDとGIDの違いをチェックします。
ps -eo uid,gid,egid,args | grep Unicorn
注:上記のフック後のユニコーンは私には機能しませんでした。これ以外は何も機能しませんでした。
同じ問題が発生しました。最終的に私のために働いたのは、after_fork do |server, worker|
ブロックのUnicorn構成で次のように設定することでした:(これはgithubUnicorn構成からのものです)
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