When I run cap deploy:update I get the error below, indicating that bundle is not found. When I run echo $PATH from cap shell the /var/lib/gems/1.9.1/bin path which contains bundle is missing, however, this path is in both /etc/profile and ~/.bashrc. Anyone know how to solve this problem?
[192.168.10.100] executing command
*** [err :: 192.168.10.100] sh:
*** [err :: 192.168.10.100] bundle: not found
*** [err :: 192.168.10.100]
command finished in 25ms
failed: "sh -c 'bundle install --gemfile /data/www/apps/my_app/releases/201104
04163717/Gemfile --path /data/www/apps/my_apps/shared/bundle --deployment --qui
et --without development test'" on 192.168.10.100
To avoide such problem you should have most recent versions of RVM (currently it is 1.13.5) installed in both places: locally and on remote server.
Next, check if your deploy.rb has
require "rvm/capistrano"
require "bundler/capistrano"
This line is not needed anymore:
$:.unshift(File.expand_path('./lib', ENV['rvm_path']))
Hope this will help
Ok, I've recently had some experience with this. Looks like there are a couple of ways that this problem can be solved. First, you can determine if in fact the remote execution (via Capistrano) is what's messed up vs. the host itself. Looks like you've done this with the Capistrano remote shell:
$ cap shell
> echo $PATH
Good. I'll bet when you login to the machine and 'echo $PATH' there, the right stuff comes out... same here.
I've found two ways to fix this: One is to enable the environment execution in the remote host's ssh daemon. In theory this would work, but I didn't want to ask the sysadmin if it was ok to open this up. You basically edit the ssh configuration files to set the 'PermitUserEnvironment' to 'yes' and add the required environment settings to the deploy user's ~/.ssh/environment file -- your system-specific man pages are probably better than my trying to generalize.
I opted for what seems rather hackish, and has the drawback that it is global for all hosts you deploy the app to (so if your ruby / gems locations are different on different hosts, this won't work) -- but: I added the default_environment settings to the config/deploy.rb script:
set :default_environment, {
'PATH' => "/usr/local/bin:/bin:/usr/bin:/bin:/<ruby-dir>/bin",
'GEM_HOME' => '<ruby-dir>/lib/ruby/gems/1.8',
'GEM_PATH' => '<ruby-dir>lib/ruby/gems/1.8',
'BUNDLE_PATH' => '<ruby-dir>/lib/ruby/gems/1.8/gems'
}
AMMENDED: It isn't so 'hackish' if you consider the following:
- The environment-specific deploy scripts (deploy/foo.rb) can
override the default in deploy.rb
- PermitUserEnvironment hides the configuration deep in the
.ssh directory of the deploy user; :default_environment at
least exposes it in the checked-in sources.
This also solves the problem of not being able to do remote rake tasks, etc., via Capistrano. Be aware that the Capistrano gem, at least the version I have and with my deploy set up in the "standard" way, will install the gems into the /shared/bundle
directory, which gets picked up by the app. The method I described requires a minimal subset of gems in the system directories referenced by the default environment so that the remote Capistrano commands can execute bundle, rake, etc.
You didn't say if you were using RVM (my solution doesn't); however, this solution is very close to one of the recommended RVM solutions. Alternately, you could just use the 'rvm/capistrano' solution; look for RVM Capistrano integration on the RVM website for more details.
Have you manually installed the bundler gem on the remote box? You can't use the bundle command or install any bundles until you do.
Are you using RVM ?
DaneS some possible solutions:
place
require "bundler/capistrano"
in your script as bundler now has support for capistrano
https://github.com/carlhuda/bundler/blob/1-0-stable/lib/bundler/capistrano.rb
And maybe
before "deploy:cold",
"deploy:install_bundler"
task :install_bundler, :roles => :app do
run "type -P bundle &>/dev/null || { gem install bundler --no-rdoc --no-ri; }"
end
The install_bundler task will only be installed if not found.
Related
I am not good with devops. I had created a user called deploy. Previously I could ssh into my server then
su deploy
and run
RAILS_ENV=production bundle exec rails c
.
Some days ago, I completely forgot that I had a user called deploy. Being the root user, I installed ruby using rvm. RVM was already installed.
Now I remember that I have a user called deploy. I ran su deploy then ran
RAILS_ENV=production bundle exec rails c
I got the following error
The program 'bundle' is currently not installed. To run 'bundle'
please ask your administrator to install the package 'ruby-bundler'
Before I had installed ruby in super admin env I could run bundle in the deploy user env.
Is there a way to fix this?
PS: My capistrano deployment script is running without any problem even if it is being deployed by the "deploy" user
The problem is that when you ssh into the directory, at the directory, no .ruby-version file exists, so it use the default ruby version(run which ruby to see the exactly path), not the rvm ruby version, so it can't find the installed gems like bundler.
It's a environment problem.The capistrano deployment is working because you have assign ruby version in your deploy.rb like
set :rvm_ruby_version, 'ruby-2.2.2#zhitaotao'
so it can find correct ruby version, then find installed gems for the version.
The solution is add a file called .ruby-version, set the content to something like ruby-2.3.1.
If this not works, i suggest to reinstall ruby, bundler, and run bundle install for deploy user. We need to make sure that at the production directory, the ruby version is matched with the ruby version assigned in the deploy.rb.
I can manually run bundle install and get something sane back, but when I let Puppet provision a Vagrant box, this happens the second time (the first I get successful output).
[default] Running provisioner: Vagrant::Provisioners::Puppet...
[default] Running Puppet with /tmp/vagrant-puppet/manifests/default.pp...
stdin: is not a tty
/opt/vagrant_ruby/lib/ruby/site_ruby/1.8/rubygems.rb:900:in `report_activate_error': Could not find RubyGem puppet (>= 0) (Gem::LoadError)
from /opt/vagrant_ruby/lib/ruby/site_ruby/1.8/rubygems.rb:248:in `activate'
from /opt/vagrant_ruby/lib/ruby/site_ruby/1.8/rubygems.rb:1276:in `gem'
from /opt/vagrant_ruby/bin/puppet:18
The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!
I am not requesting the puppet gem anywhere, it's not in my Gemfile and my manifest does not require it either. Why is the puppet gem being looked for, and how do I get rid of this error?
I'm using https://github.com/blt04/puppet-rvm for provisioning my Vagrant box with RVM and I get the same problem. Unsetting "default_use => true" indeed fixes it. Unfortunately then you have to manually select your target Ruby once you ssh'd into the box.
Alternatively, you can add the puppet gem explicitly to the default Ruby in your manifest (not to any gemset, just to the Ruby itself). It still kept bugging me about some config file for hiera (??) missing, but it seemed to work anyway.
I'm wondering if RVM on Vagrant is even worth the hassle. The whole point about creating a Vagrant box is to have an isolated environment for a single project, so why would I need multiple Rubies/Gemsets then?
Puppet is run by you VM on your VM. Make sure the gem is still installed for users vagrant and root.
It could be a switch of your default ruby version too (system vs installed via rvm or rbenv ?).
Hope this helps.
Puppet is expected to be run by vagrant with the system ruby, but RVM may default to your chosen installed ruby. To work around this, I did this (a pretty ugly hack) while still having a default ruby when logging in normally:
In your vagrant file:
# setup working dir only to exploit in below
working_dir = '/home/vagrant/puppet'
config.vm.provision :shell, :inline => "mkdir -p #{working_dir}"
config.vm.provision "puppet" do |puppet|
# [ ... Your config ... ]
# before puppet is run, vagrand `cd`s into the working directory, failing to escape it.
puppet.working_directory = "#{working_dir}; rvm use system || true"
end
Due to an escaping bug/feature in the vagrant puppet provider (https://github.com/mitchellh/vagrant/blob/master/plugins/provisioners/puppet/provisioner/puppet.rb#L154) this causes vagrant to
Start out with the rvm loaded and configured with the default
Change into the given directory
Switch to the system ruby, making the gem be found again
Run puppet like on the first run without any RVM-rubies interfering with it.
I'm a new user to Capistrano and using it to deploy a rails 3.1 app. There seems to be an issue with gem installation on the remote server.
I have the following questions:
It looks like cap runs bundle install on the gemfile? Are there any dependencies for this to work successfully? I have rvm and bundler on my server. Does it need rails installed already?
I have manually set the bundle_cmd in my deploy.rb like this:
set :bundle_cmd, '/usr/local/rvm/gems/ruby-1.9.2-p290/bin/bundle'
Should this be correct?
Is there a way to have confirmation on a cap deploy that ALL the required gems are there? Or what is the best way to debug a failed bundle install on the remote server? Can you call something like cap gem-list; was hoping something like cap invoke=gem list would do it but doesn't look like it.
Edit #1
I'm getting the following error:
failed: "rvm_path=/usr/local/rvm /usr/local/rvm/bin/rvm-shell 'default' -c 'cd /data/sites/myserver/apps/myapp/releases/20111204181321 && bundle install --gemfile /data/sites/myserver/apps/myapp/releases/20111204181321/Gemfile --path /data/sites/myserver/apps/myapp/shared/bundle --deployment --quiet --without development test'" on 173.230.xxx.xxx
If I go into a previous release, and run bundle install, it says that everything installed correctly which it didn't.
It says:
Your bundle is complete! It was installed into /data/sites/myserver/apps/myapp/shared/bundle
but if I go in there, there is nothing other than the ruby 1.9.1 which to the best of my knowledge I didn't install (using ruby 1.9.2-p290)
Is there a way in capistrono to specify it not to delete the deployed release so that I can debug that explicitly? Shoud I need to hardcode the path to my bundler in my deploy.rb script?
thx again
EDIT 2
If I go into the current release at:
/data/sites/myserver/apps/myapp/current
and run:
$ which bundle
/usr/local/rvm/gems/ruby-1.9.2-p290/bin//bundle
I get:
$ bundle install
/usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/site_ruby/1.9.1/rubygems/dependency.rb:247:in `to_specs': Could not find bundler (>= 0) amongst [minitest-1.6.0,rake-0.8.7, rdoc-2.5.8] (Gem::LoadError)
from /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/site_ruby/1.9.1/rubygems/dependency.rb:256:in `to_spec'
from /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/site_ruby/1.9.1/rubygems.rb:1210:in `gem'
from /usr/local/rvm/gems/ruby-1.9.2-p290/bin/bundle:18:in `<main>'
You dont need to have rails installed already, but I do think that you need to have bundler installed. gem install bundler
You can use RVM and bundler integration from capistrano. In that case you dont have to set the path to bundler.
$:.unshift(File.expand_path('./lib', ENV['rvm_path']))
require "rvm/capistrano"
require "bundler/capistrano" # Load RVM's capistrano plugin.
set :rvm_type, :system
set :rvm_ruby_string, '1.9.2#gemset_name'
You can use 'cap shell' to run commands through Capistrano on the server. You could use this to check the installation of all your gems. Use cap -T to see all possibilities.
On a side note, do you really need rvm gemsets for your app? I use RVM to install and update my rubies on my production server, but I let Bundler handle the separation of my gems. Since the default bundler settings in production put all your gems in vendor/bundle, this already separates your gems from each other. This works great with Capistrano too.
See a similar question and answer here. Some more information a capistrano/bundler/rvm/passenger setup can be find in this tutorial.
During capistrano deployment of a Rails3 app, I want my server to install gems, using Gemfile.lock, every time I deploy. And since my server does not have rvm and all.. All gems should be installed as system gems.
To install system gems, we need to put sudo gem install anygem or for bunder, we need to give command sudo bundle install inside our current directory of capistrano deployment structure.
Everytime, I deploy, my deployment breaks at the gems installation process. I need sudo bundle install to run. For that, I need a deployment hook for capistrano. The prebuilt ones that are supplied by bundler gem itself is not working for me. My confusion boils down to these three questions.
When should I invoke the sudo bundle install command in the deployment process - i mean after which capistrano task ?
For running sudo commands using capistrano, what declarations I should specify in my cap file ? Note - i already have pushed my public key as authorized keys in my server.
How should the bundle install hook be written in the cap file ?
Please help.
Adding require "bundler/capistrano" to your deploy.rb should just work. It should declare a folder to install gems to that do not require sudo access, regardless of rvm.
Is that still failing for you?
If you run bundle install --deployment you shouldn't need sudo access as the gems should be installed to vendor/bundle in your app rather than to the system itself.
i use that in my deploy.rb:
require "bundler/capistrano"
... deploy recipe
namespace :bundle do
desc "Install bundles into application"
task :install, :roles => [:app] do
run "cd #{current_path} && LC_ALL='en_US.UTF-8' bundle install --deployment --without test"
end
end
Then after normal deploy i run "cap bundle:install"
note: Using UTF-8 to prevent ruby1.9 ASCII chars problems.
I have a basic Rails 3 app working locally on my development box, but want to test out deploying early on to make sure everything works. I'm using Capistrano to deploy.
When I run cap deploy (after all the other necessary setup), it breaks on this command with this error:
[...]
* executing 'bundle:install'
* executing "bundle install --gemfile /var/www/trex/releases/20100917172521/Gemfile --path /var/www/trex/shared/bundle --deployment --quiet --without development test"
servers: ["www.[my domain].com"]
[www.[my domain].com] executing command
** [out :: www.[my domain].com] sh: bundle: command not found
command finished
[...]
So it looks like it can't find the bundle command on the server.
However, when I log in to the server...
$ ruby -v
ruby 1.9.2p0 (2010-08-18 revision 29036) [x86_64-linux]
$ rails -v
Rails 3.0.0
$ bundle -v
Bundler version 1.0.0
...the bundle command works just fine.
What could be going wrong?
-
(Furthermore, for completeness:)
$ which ruby
~/.rvm/rubies/ruby-1.9.2-p0/bin/ruby
$ which rails
~/.rvm/gems/ruby-1.9.2-p0/bin/rails
$ which bundle
~/.rvm/gems/ruby-1.9.2-p0/bin/bundle
UPDATE:
For RVM >= 1.11.3, you should now just use the rvm-capistrano gem. For older RVM >= 1.0.1, the answer below still applies.
ORIGINAL ANSWER:
Okay, though I still haven't gotten a full cap deploy to work, I did fix this problem. The problem was Capistrano trying to use a different path for Bundler (and other gems) than the RVM paths.
Check your Capistrano path by doing cap shell, then echo $PATH. You'll probably see your standard /usr/local/bin and /usr/bin, but that's not where RVM has Bundler, et al., stored.
Edit your Capistrano config/deploy.rb file, and add the following lines, per these instructions:
# Add RVM's lib directory to the load path.
$:.unshift(File.expand_path('./lib', ENV['rvm_path']))
# Load RVM's capistrano plugin.
require "rvm/capistrano"
set :rvm_ruby_string, '1.9.2'
set :rvm_type, :user # Don't use system-wide RVM
That finally got Capistrano to see Bundler and start loading gems appropriately.
Bundler isn't found because .bash_profile is not being loaded and thus your PATH is wrong. This is probably because you have the RVM script in .bash_profile.
The simple answer is to move the RVM script from .bash_profile to .bashrc and Capistrano should be able to find it (also verify that .bash_profile sources .bashrc).
Capistrano uses SSH to execute commands on the server via a non-interactive shell. This shell session will source .bashrc but not .bash_profile. I added an ECHO statement to both and ran an LS via SSH. You can see in the results below that only .bashrc is sourced:
$ ssh user#123.amazonaws.com ls
.bashrc loaded
git
file1
file2
I had an identical problem using rbenv. The solution was to take the rbenv specific lines from the bottom of my .bashrc file and put them at the top. The first line of my .bashrc file was returning aborting if the shell wasn't running in interactive mode.
That last line should actually be
set :rvm_type, :user
that is, user must be a symbol and not a variable, otherwise you'll get
undefined local variable or method `user'
No rvm/capistrano worked for me. The best solution I found was adding to deploy.rb file the following line (it's for non system-wide RVM):
set :bundle_cmd, 'source $HOME/.bash_profile && bundle'
It was my understanding that the bundle command is not found because the PATH variable, defined in the user's ~/.bash_profile, isn't loaded by Capistrano.
To get around this I have created a task :bundle_gems.
task :bundle_gems do
run "cd #{deploy_to}/current && export PATH=/usr/local/pgsql/bin:/opt/ruby-enterprise-X.X.X/bin:$PATH && bundle install vendor/gems"
end
Note that I also include the path to PostgreSQL binaries - installation of the pg gem was failing because they could not be found, even when bundle could be found.
This seems like a messy approach, though. Presumably there is a more 'global' place to define paths to binaries that I don't know about.
Update 23/12
To add a directory to $PATH for all users: https://serverfault.com/questions/102932/adding-a-directory-to-path-in-centos
However this still won't be loaded because it is a non-interactive non-login shell.
One suggestion was to add the paths to /etc/bashrc: How do I set $PATH such that `ssh user#host command` works?
However this also didn't work for me. I believe its because SSH doesn't load /etc/bashrc either.
Another suggestion was to edit ~/.ssh/environment: http://www.ruby-forum.com/topic/79248. However this seems almost as messy as specifying the paths in deploy.rb.
This one worked for me:
set :bundle_cmd, 'source $HOME/.bash_profile && bundle'
I tried a number of the suggestions. Had problems with setting the paths in the deploy.rb file for the RVM environment. My final solution was to include the following:
In the config/deploy.rb file add:
require "bundler/capistrano"
Also in config/deploy.rb, or in my case config/production.rb as I was using the multistage option for Capistrano
after "deploy", "rvm:trust_rvmrc"
This step simply ensures that we stop getting the 'do you want to trust the .rvmrc file' and it calls a task in the deploy.rb file such as:
namespace :rvm do
task :trust_rvmrc do
run "rvm rvmrc trust #{release_path}"
end
end
After putting in these slight changes I was able to run cap production deploy which checked out the code; executed the asset pipeline deployment, linked up the release folder to current, executed bundle install and cleaned up.