Search code examples
ruby-on-railsruby-on-rails-4continuous-deploymentcapistrano3rvm-capistrano

How to have sudo -u user for all capistrano tasks that are to be run?


NOTE: I am using Capistrano 3.2.1 and Rails 4.1.1.

Basically I need Capistrano to append sudo -u deploy-user for all the tasks by default because of the server permissions arrangement on my-remote-server.

This is my config/deploy.rb file:

# config valid only for Capistrano 3.1

set :stages, %w(qaenv production)
set :default_stage, 'production'

set :application, "my_rails_app"
set :repo_url, '[email protected]:repositories/my_rails_app.git'
set :domain, "my-remote-server"
set :database, "mysql"
set :use_sudo, true

#set :user, "surya"
set :deploy_user, "deploy-user"
set :migration_user, "www"
set :sample_user, "sample"
set :ssh_options, { forward_agent: true, port: 2445 }
#set :deploy_via, :copy
set :deploy_to, "/var/www/#{fetch(:application)}"
set :branch, "master"
set :scm, :git

role :web, fetch(:domain)                         # Your HTTP server, Apache/etc
role :app, fetch(:domain)                         # This may be the same as your `Web` server
role :db,  fetch(:domain), :primary => true # This is where Rails migrations will run
set :pty, true
set :log_level, :trace
set :sudo, ' -u deploy-user ' # I hoped that it'll work, but it doesn't
set :linked_files, %w{config/database.yml}

Here's the error trace I get:

[surya@my-server my_rails_app]$ cap qaenv deploy:check:directories
INFO[0fe8c58d] Running /usr/bin/env mkdir -pv /var/www/my_rails_app/shared /var/www/my_rails_app/releases on my-remote-server
Text will be echoed in the clear. Please install the HighLine or Termios libraries to suppress echoed text.
Password: MySecretPassword
cap aborted!
Exception while executing on host my-remote-server: Authentication failed for user deploy-user@my-remote-server
/usr/local/rvm/gems/ruby-2.1.2-p95/gems/net-ssh-2.9.1/lib/net/ssh.rb:219:in `start'
/usr/local/rvm/gems/ruby-2.1.2-p95/gems/sshkit-1.5.1/lib/sshkit/backends/connection_pool.rb:50:in `call'
/usr/local/rvm/gems/ruby-2.1.2-p95/gems/sshkit-1.5.1/lib/sshkit/backends/connection_pool.rb:50:in `create_new_entry'
/usr/local/rvm/gems/ruby-2.1.2-p95/gems/sshkit-1.5.1/lib/sshkit/backends/connection_pool.rb:22:in `checkout'
/usr/local/rvm/gems/ruby-2.1.2-p95/gems/sshkit-1.5.1/lib/sshkit/backends/netssh.rb:179:in `with_ssh'
/usr/local/rvm/gems/ruby-2.1.2-p95/gems/sshkit-1.5.1/lib/sshkit/backends/netssh.rb:131:in `block in _execute'
/usr/local/rvm/gems/ruby-2.1.2-p95/gems/sshkit-1.5.1/lib/sshkit/backends/netssh.rb:128:in `tap'
/usr/local/rvm/gems/ruby-2.1.2-p95/gems/sshkit-1.5.1/lib/sshkit/backends/netssh.rb:128:in `_execute'
/usr/local/rvm/gems/ruby-2.1.2-p95/gems/sshkit-1.5.1/lib/sshkit/backends/netssh.rb:66:in `execute'
/usr/local/rvm/gems/ruby-2.1.2-p95/gems/capistrano-3.2.1/lib/capistrano/tasks/deploy.rake:47:in `block (4 levels) in <top (required)>'
/usr/local/rvm/gems/ruby-2.1.2-p95/gems/sshkit-1.5.1/lib/sshkit/backends/netssh.rb:54:in `instance_exec'
/usr/local/rvm/gems/ruby-2.1.2-p95/gems/sshkit-1.5.1/lib/sshkit/backends/netssh.rb:54:in `run'
/usr/local/rvm/gems/ruby-2.1.2-p95/gems/sshkit-1.5.1/lib/sshkit/runners/parallel.rb:13:in `block (2 levels) in execute'
Tasks: TOP => deploy:check:directories
(See full trace by running task with --trace)
[surya@my-server my_rails_app]$

If you look at the error trace line:

INFO[0fe8c58d] Running /usr/bin/env mkdir -pv /var/www/my_rails_app/shared /var/www/my_rails_app/releases on my-remote-server
Text will be echoed in the clear. Please install the HighLine or Termios libraries to suppress echoed text.
Password: MySecretPassword
cap aborted!
Exception while executing on host my-remote-server: Authentication failed for user deploy-user@my-remote-server

It tries to run:

/usr/bin/env mkdir -pv /var/www/my_rails_app/shared /var/www/my_rails_app/releases

and what I want it do is:

sudo -u deploy-user /usr/bin/env mkdir -pv /var/www/my_rails_app/shared /var/www/my_rails_app/releases

What do I do to make sure that my all cap tasks are run with sudo -u deploy-user?


Solution

  • Make sure your deploy user has passwordless sudo access, and in your deploy.rb file make sure that use_sudo is set to true.

    First, add this to your deploy.rb file.

    set :use_sudo, true
    

    Then edit your sudoers file and give your deploy user passwordless sudo. Just open the sudoers file:

    sudo visudo 
    

    Then add this line to the bottom of the file (assuming your user is named "deploy")

    deploy ALL=(ALL) NOPASSWD:ALL
    

    Note: This should not be done lightly. This is a security risk, and you should understand the implications before you do it. Granted, if you NEED sudo access for your deploy user then this is how you do it. For more details on why passwordless sudo is bad check out the documentation:

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