33

I want to write a recipe with Capistrano 3 executing a task on the remote server with sudo.

With Capistrano 2 this could be done for example:

default_run_options[:pty] = true

task :hello do
  run "#{sudo} cp ~/something /something"
end

With Capistrano 3 I found:

set :pty, true

But I could not get to execute a task running with sudo.

How can I run a task with sudo?

crimi
  • 746
  • 1
  • 7
  • 8
  • @Rubyman `:use_sudo` is not a valid setting for Capistrano 3. See this [related ticket](https://github.com/capistrano/capistrano/issues/920) – milkfarm May 22 '15 at 21:19

5 Answers5

21

The Capistrano 3 guide recommends the use of passwordless sudo. This allows your less-priveleged user execute the sudo command without having to enter a password via the PTY.

You can use the task that Kentaro wrote above, and add something like the following to your /etc/sudoers file:

deploy ALL=NOPASSWD:/bin/cp ~/something /something

http://www.capistranorb.com/documentation/getting-started/authentication-and-authorisation/#toc_8

Ian
  • 509
  • 3
  • 6
19

I usually write like this:

task :hello do
  on roles(:all) do |host|
    execute :sudo, :cp, '~/something', '/something'
  end
end

Edit

Capistrano 3 does not support sudo with password.

However, I created a small gem, which enables you to use sudo with password in Capistrano 3 task.

Add sshkit-sudo to your application's Gemfile:

# Gemfile
gem 'sshkit-sudo'

And require 'sshkit/sudo' in you Capfile:

# Capfile
require 'sshkit/sudo'

Now, you can execute a command with sudo as follows:

task :hello do
  on roles(:all) do
    sudo :cp, '~/something', '/something'
  end
end
Kentaro Imai
  • 654
  • 6
  • 11
  • 1
    I already tried this to. The console displays this: INFO [5d8e920e] Running /usr/bin/env sudo cp ~/something /something on example.local DEBUG [5d8e920e] Command: /usr/bin/env sudo cp ~/something /something DEBUG [5d8e920e] [sudo] password for main: I can also insert my password, which is displayed by the way, but the task does not continue on return. – crimi Nov 18 '13 at 06:27
  • If you really want to use sudo with password, you should use capistrano 2. – Kentaro Imai Nov 20 '13 at 20:41
  • This works. Thanks. If someone is looking to do apt-ge with sshkit-sudo try `sudo :'apt-get', '-y install curl'` – Srikanth Jeeva Jan 23 '18 at 23:24
  • `sudo` instead of `execute` did the job for me. thx – mFlorin May 03 '22 at 20:16
15

To resolve this issue I needed to add set :pty, true to my deploy.rb file.

I can now run the following:

# config valid only for Capistrano 3.1
lock '3.1.0'

set :application, 'APP_NAME'
set :pty, true
set :ssh_options, {:forward_agent => true}

namespace :deploy do

  desc 'Restart NGINX'
  task :restart do
    on roles(:app), in: :sequence, wait: 1 do
       execute :sudo, "./restart.sh"
    end
  end

end

This task basically runs a shell script called restart.sh that has a command within sudo service nginx restart.

ajtrichards
  • 29,723
  • 13
  • 94
  • 101
  • 1
    Yes, only after setting `set :pty, true` can you execute sudo commands with capistrano 3. Otherwise you will get `sudo stderr: sudo: no tty present and no askpass program specified` errors. – Bibek Shrestha Sep 05 '14 at 11:00
  • 4
    When I do this it asks me for my password, but I cannot "enter" it, it just gives me newlines.. – Tim Baas Jan 03 '17 at 13:32
  • @TimBaas were you able to solve your issue ? I am also stuck with the same problem – aelor Feb 06 '17 at 15:33
  • @aelor did you solve that problem, I'm stuck in the same place – Arian Faurtosh Mar 24 '17 at 00:28
  • @ArianFaurtosh @aelor - make sure you've added `set :ssh_options, {:forward_agent => true}` – ajtrichards Mar 24 '17 at 06:26
  • @ArianFaurtosh basically the log that you are seeing is not an interactive shell. So you cannot input anything. Now, to solve this, you can do either of two things: a) add your user to with no password access inside sudoers file or b) do a `bundle install --deployment`, the deployment flag makes sure that the gems get installed within the vendor directory for which the user already has access. The latter solved my issue – aelor Mar 27 '17 at 15:41
3

you want "as user do end", like

as "root" do
  execute :something
end
Koen.
  • 25,449
  • 7
  • 83
  • 78
Joe McDonagh
  • 163
  • 6
  • I think this is the Capistrano 2.x syntax? – A--- Sep 01 '15 at 21:37
  • AFAIK as-user-do is a new cap 3 construct. I could be wrong but I have been using cap since its infancy and cannot recall ever seeing this construct until the newer version. But- my memory is certainly fallible. – Joe McDonagh Sep 03 '15 at 14:21
1

If you really need to use sudo you can always map the command like SSHKit.config.command_map[:rm] = 'sudo rm' which will make execute :rm into the proper rm command invoked with sudo. If your deploy user is in the sudoers things will work as expected.