orangain flavor

じっくりコトコト煮込んだみかん2。知らないことを知りたい。

Capistranoでのsudoの書き方

はじめに

Ruby製のデプロイツールであるCapistranoを使ってみました。いろいろなレシピを眺めていると、sudoの書き方が次のようにいろいろあって違いがわからなかったので、調べてみました。

sudo "hoge"            # (1) sudoアクション
run "sudo hoge"        # (2) 文字列 "sudo"
run "#{sudo} hoge"     # (3) 文字列 "#{sudo}"
run "#{try_sudo} huge" # (4) 文字列 "#{try_sudo}"

なお、対象のバージョンは、執筆時点で最新の2.14.2です。

(1) sudoアクション

この書き方は、deprecatedなので今は使いません。

2.x DSL Action Invocation Sudo · capistrano/capistrano Wiki

(2) 文字列 "sudo"

書いてある通りにsudoコマンドが実行されます。sudoにパスワードが必要な場合をうまくハンドルできないことがあるので、次の"#{sudo}"を使うべきです。

(3) 文字列 "#{sudo}"

これは変数sudoが展開されるようにも見えますが、実際はsudoメソッドの呼び出し結果が展開されます。使ってみるとわかりますが、"#{sudo}"は、"sudo -p 'sudo password: '"と展開されます。

-pオプションでプロンプトを明示的に指定することで、パスワードが要求されていることをCapistranoが確実に検知できる仕組みです。sudoしたいときは、この書き方を使いましょう。

#{sudo :as => 'bob' }"のようにして、ユーザーを指定することもできます。

2.x DSL Action Invocation Sudo · capistrano/capistrano Wiki

(4) 文字列 "#{try_sudo}"

設定:use_sudotrueの場合(デフォルト)はsudoを使い、falseの場合はsudoを使いません。Capistranoがデフォルトで定義しているデプロイプロセスで使われるものなので、ユーザーがdeploy.rbに書くべきものではないと思われます。

:use_sudoの解説 には、次のように書いてあります。

Defines for the default Rails deployment recipes whether we want to usesudo or not. sudo is a unix tool for executing commands as the root user. To use it, your user must have password-less sudo access enabled. If you’re using shared hosting where sudo access may not be enabled for your user, you should set:use_sudo to false. In general, if you can get away without using sudo, you should avoid it. For example, 37signals now uses a system where they have a special deployment user, and always deploy as that user.

sudoを使わずに済むなら:use_sudofalseにしてsudoを使わないようにしましょうと書いてあります。37signalsでは、デプロイ専用のユーザーを用意して、デプロイは常にそのユーザーで行っているそうです。

なお、歴史的経緯はよくわかりませんが、:use_sudotrueにしている(デフォルト)場合、cap deploy:setuproot権限でユーザーが作られてしまうため、そのままではcap deploygit cloneできないという問題があります。

このことからも、:use_sudofalseにすべきでしょう。

まとめ

  1. sudoしたいときは、run "#{sudo} huge"と書きましょう。

  2. set :use_sudo, false として、デプロイ専用のユーザーでデプロイしましょう。