I am deploying my application to a new server which has everything installed.
I am using the following capistrano deploy.rb:
require "capistrano/ext/multistage"
require "bundler/capistrano"
set :default_environment, {
'ORACLE_HOME' => "/opt/oraclient/64/11.2.0.2/",
'LD_LIBRARY_PATH' => "$ORACLE_HOME/lib:/usr/local/lib",
'PATH' => "/opt/ruby/bin:$PATH:$ORACLE_HOME/bin"
}
SECURE_FILES = ['database.yml', 'ldap.yml', 'initializers/secret_token.rb']
set :application, "myapp"
set :use_sudo, false
set :scm, :git
set :repository, "ssh://git#hostname:7999/web/myapp.git"
set :user, "webuser"
set :deploy_via, :remote_cache
after "deploy:update_code", "custom:create_symlinks", "custom:assets_precompile", "custom:miscellaneous"
after "deploy", "deploy:migrate"
after "deploy", "deploy:cleanup"
namespace :deploy do
desc "Restarting mod_rails with restart.txt"
task :restart, :roles => :app, :except => { :no_release => true } do
run "touch #{current_path}/tmp/restart.txt"
end
[:start, :stop].each do |t|
desc "#{t} task is a no-op with mod_rails"
task t, :roles => :app do ; end
end
namespace :web do
desc "Enable maintenance mode for apache"
task :enable_maintenance, :role => :web do
run "mkdir -p #{shared_path}/system"
on_rollback { run "rm -f #{shared_path}/system/maintenance.html" }
page = File.read('public/maintenance.html')
put page, "#{shared_path}/system/maintenance.html", :mode => 0644
end
desc "Disable maintenance mode for apache"
task :disable_maintenance, :role => :web do
run "rm -f #{shared_path}/system/maintenance.html"
end
end
end
namespace :custom do
desc "Creating config, bundler-GEMS symlinks"
task :create_symlinks, :roles => :app do
#Secure Configuration File Symlinks
SECURE_FILES.each do |link|
fobj = "#{release_path}/config/#{link}"
run <<-CMD
if [ -e #{fobj} ]; then rm -f #{fobj}; fi;
rm -f #{previous_release}/config/#{fobj};
ln -s #{vormetric_path}/#{application}/#{link} #{fobj};
CMD
end
#Bundler GEM Installation Symlink
shared_bundler_dir = File.join(shared_path, 'bundle')
release_bundler_dir = File.join(current_release, 'vendor/bundle')
run "ln -s #{shared_bundler_dir} #{release_bundler_dir}"
end
desc "Assets Pre-Compilation"
task :assets_precompile, :roles => :app do
run "cd #{current_release} && RAILS_ENV=#{rails_env} bundle exec rake assets:precompile"
end
desc "Miscellaneous Tasks"
task :miscellaneous, :roles => :app do
run "chmod -f +w #{current_release}/db/schema.rb"
end
end
This is box-specific deploy script myhostname.rb:
server "myhostname", :app, :web, :db, :primary => true
set :deploy_to, "/opt/web/var/myapp"
set :rails_env, "customertest"
set :branch, "staging"
Now the remote box does not have access to internet, but I have all my gems stored under vendor/cache. So it should pick up from there.(vendor/cache has nokigiri under /myapp/current/vendor/cache on remote server)
When i run
cap deploy servername
, i get the following error:
** [out :: myhost] An error occurred while installing nokogiri (1.5.9), and Bundler cannot
** [out :: myhost] continue.
** [out :: myhost] Make sure that `gem install nokogiri -v '1.5.9'` succeeds before bundling.
My remote box where the code is supposed to be deployed has the following folders set up:
/opt/web/var/myapp
/opt/web/var/myapp/current(where all the code is cloned currently)
/opt/web/var/myapp/releases
/opt/web/var/myapp/shared
I am not sure how it i supposed to pick up and install the gem.
This quote from bundler docs might be relevant (emphasis mine):
http://bundler.io/v1.9/bundle_package.html
By default, if you simply run bundle install after running bundle package, Bundler will still connect to rubygems.org to check whether a platform-specific gem exists for any of the gems in vendor/cache.
This behavior can be avoided by instead running bundle install --local. Note that this requires you to have the correctly platformed version for all of your gems already cached. The easiest way to achieve this is to run bundle package on an identical machine and then check in those vendored gems.
So, in short, you need to pass the --local flag when running bundler in the production server to avoid connecting to rubygems altogether.
The solution for use with capistrano is to set this variable in you deploy.rb file:
# deployment and quiet are used by default, we add the local flag
set :bundle_flags, "--deployment --quiet --local"
Related
I am trying to deploy and I do not want the Gemfile.lock in version control. But when it's removed I get the following error.
* executing "cd /var/www/vhosts/my-site/releases/20120628162217 && bundle install -- gemfile /var/www/vhosts/mysite/releases/20120628162217/Gemfile --path /var/www/vhosts/my-site/shared/bundle --deployment --quiet --without development test cucumber analytics"
servers: ["staging-beta.my-site.com"]
[staging-beta.my-sitehealth.com] executing command
** [out :: staging-beta.my-site.com] The --deployment flag requires a Gemfile.lock. Please make sure you have checked your Gemfile.lock into version control before deploying.
command finished in 332ms
Here is my deploy.rb file:
require 'thinking_sphinx/deploy/capistrano'
set :rvm_ruby_string, '1.9.3'
# Ignore the .git directory when creating a release
set :copy_exclude, ".git*"
set :stages, %w(production staging rails_ec2_west_staging vagrant analytics highgroove ec2_highgroove stage_analytics ec2_staging highgroove_staging ec2_chef ec2_sphinx_chef solr_staging ec2_sphinx_prod_chef)
set :default_stage, "staging"
set :bundle_without, [:development, :test, :cucumber, :analytics]
require 'bundler/capistrano'
set :custom_symlinks, {}
require 'capistrano/ext/multistage'
if ARGV.first == 'ec2_staging'
require 'rvm/capistrano'
# for dual deploys on ec2 staging
set :application, "my-site3"
else
set :application, "my-site"
end
set :use_sudo, false
set :user, "www-data"
set :group, "www-data"
ssh_options[:forward_agent] = true
set :branch, $1 if `git branch` =~ /\* (\S+)\s/m
set :scm, :git
set :repository, "git#github.com:my-company/my-site3.git"
set :deploy_to, "/var/www/vhosts/#{application}"
set :deploy_via, :remote_cache
set :deploy_env, 'production'
# If you are using Passenger mod_rails uncomment this:
# if you're still using the script/reapear helper you will need
# these http://github.com/rails/irs_process_scripts
namespace :deploy do
task :start do ; end
task :stop do ; end
task :restart, :roles => :app, :except => { :no_release => true } do
run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}"
end
task :seed, :roles => :db do
rake = fetch(:rake, "rake")
rails_env = fetch(:rails_env, "production")
run "cd #{current_path} && #{rake} RAILS_ENV=#{rails_env} db:seed"
end
end
namespace :assets do
task :precompile do
run "cd #{current_path} && #{rake} RAILS_ENV=#{rails_env} my-site-web:assets:precompile"
end
end
task :uname do
run "uname -a"
end
after "deploy:update", "deploy:cleanup"
after "deploy:update", "assets:precompile"
require './config/boot'
#require 'airbrake/capistrano'
It's the best practice to include the gemfile.lock. From Bundlers rational page: http://gembundler.com/rationale.html
This is important: the Gemfile.lock makes your application a single package of both your own code and the third-party code it ran the last time you know for sure that everything worked. Specifying exact versions of the third-party code you depend on in your Gemfile would not provide the same guarantee, because gems usually declare a range of versions for their dependencies.
I've recently had to make some updates to an app that I haven't touched in about a year. When attempting to deploy with Capistrano (via Github), I get this error:
[deploy:update_code] exception while rolling back: IOError, closed stream
Full logged error here: https://gist.github.com/2829751
I reinstalled my server's SSH key after the Github SSH security scare. Nothing should have changed on the remote server, and deploying worked fine previously. The only significant change on my local system is moving to RVM.
Any ideas what's causing the error?
Here's my deploy.rb file, if that helps:
default_run_options[:pty] = true
set :domain, 'xxx.xxx.xxx'
set :repository, "XXX MY REPO XXX"
set :branch, 'master'
set :password, 'XXXXXXX'
set :deploy_to, "/var/www/#{domain}"
set :scm, :git
set :repository_cache, "git_cache"
set :deploy_via, :remote_cache
ssh_options[:paranoid] = false
set :user, "XXX"
set :runner, user
set :use_sudo, true
set :rails_env, 'production'
role :app, domain # multiple domains can be added here for parallel deployment (i.e. test_app)
role :web, domain
role :db, domain, :primary => true
namespace :deploy do
task :start, :roles => :app do
run "touch #{release_path}/tmp/restart.txt"
end
task :stop, :roles => :app do
# Do nothing.
end
desc "Restart Application"
task :restart, :roles => :app do
run "touch #{release_path}/tmp/restart.txt"
end
end
deploy.task :cold do
deploy.update
deploy.create_db
deploy.migrate
deploy.restart # Change to start if we're using mongrels
end
after "deploy:update_code", :update_config
after "deploy:restart", "delayed_job:restart"
after "deploy", "deploy:cleanup"
#links config files from shared to the release path and mongrel path after deployment
desc "Create all symlinks and files needed for app activation ofter deployment"
task :update_config, :roles => :web do
run "ln -s -f /var/www/#{domain}/shared/database.yml #{release_path}/config/database.yml"
run "ln -s -f /var/www/#{domain}/shared/app.yml #{release_path}/config/app.yml"
run "ln -s -f /var/www/#{domain}/shared/cache #{release_path}/public/cache"
run "ln -s -f /var/www/#{domain}/shared/survey_cache #{release_path}/public/surveys"
run "ln -s -f /var/www/#{domain}/shared/surveys #{release_path}/surveys"
end
desc "changes ownership to cbdsm:git"
task :update_permissions, :roles => :web do
sudo "chown -R #{user}:git /var/www/#{domain}"
end
namespace :delayed_job do
desc "Start the delayed_job process"
task :start, :roles => :app do
run "cd #{current_path} && RAILS_ENV=#{rails_env} script/delayed_job -n 3 start"
end
desc "Stop the delayed_job process"
task :stop, :roles => :app do
run "cd #{current_path} && RAILS_ENV=#{rails_env} script/delayed_job stop"
end
desc "Restart the delayed_job process"
task :restart, :roles => :app do
delayed_job.stop
delayed_job.start
end
end
UPDATE: This seems to be a problem set :use_sudo, true. Removing that line and any commands which require sudo seemed to fix the problem. It's still not entirely clear to me what changed--that made that line problematic. It worked fine before.
Additionally, I removed the default_run_options[:pty] = true line.
As posted above:
This seems to be a problem set :use_sudo, true. Removing that line and any commands which require sudo seemed to fix the problem. It's still not entirely clear to me what changed--that made that line problematic. It worked fine before.
Additionally, I removed the default_run_options[:pty] = true line.
In these cases post the /config/deploy.rb would help...
BTW, how do you set the :deploy_via setting? Try to change this to :remote_cache (from :copy):
set :deploy_via, :remote_cache
and see what happens.
I keep getting the following error when trying to deploy my app with the bundle/install option:
failed: "sh -c 'cd /home/deploy/swamp/releases/20110903003336
&& bundle install --gemfile /home/deploy/swamp/releases/20110903003336/Gemfile
--path /home/deploy/swamp/shared/bundle --deployment --quiet
--without development test'" on 12.345.678.98
**Update - looks like I missed an error:
[err :: 12.345.678.98] sh: bundle: not found
I've tried this in my deploy.rb:
require "bundler/capistrano"
and I've tried this:
namespace :bundler do
task :create_symlink, :roles => :app do
shared_dir = File.join(shared_path, 'bundle')
release_dir = File.join(current_release, '.bundle')
run("mkdir -p #{shared_dir} && ln -s #{shared_dir} #{release_dir}")
end
task :bundle_new_release, :roles => :app do
bundler.create_symlink
run "cd #{release_path} && bundle install --without test"
end
end
after 'deploy:update_code', 'bundler:bundle_new_release'
I've also moved my bundle to the vendor path with this:
bundle install --path vendor/bundle
I don't think it's a permissions problem, because I can log in manually with deploy and bundle install directly on the server no problem. Here is the entire deploy.rb file:
require "bundler/capistrano"
set :application, "swamp"
set :domain, "12.345.678.98"
set :repository, "git#github.com:***/**.git"
set :deploy_to, "/home/deploy/#{application}"
set :rails_env, 'production'
set :branch, "master"
role :app, domain
role :web, domain
role :db, domain, :primary => true
set :deploy_via, :remote_cache
set :scm, :git
set :user, "deploy"
set :runner, "deploy"
ssh_options[:port] = ****
set :use_sudo, false
after "deploy", "deploy:cleanup"
namespace :deploy do
desc "Restarting mod_rails with restart.txt"
task :restart, :roles => :app, :except => { :no_release => true } do
run "touch #{current_path}/tmp/restart.txt"
end
[:start, :stop].each do |t|
desc "#{t} task is a no-op with mod_rails"
task t, :roles => :domain do ; end
end
end
task :after_update_code do
run "ln -nfs #{deploy_to}/shared/config/database.yml #{release_path}/config/database.yml"
end
I found the solution here:
http://www.pastbedti.me/2011/06/change-path-environment-with-rails-and-capistrano/
In you config/deploy.rb add the following snippet
set :default_environment, {
'PATH' => "/opt/ruby-enterprise/bin/:$PATH"
}
Then I had to add gemfile.lock and gemfile to the repository and the BAM!
outdated
the below solution works for capistrano 2. for version 3 and up use the capistrano-rbenv plugin.
assuming you're using the bash shell and have rbenv configured in something along the lines of a bashrc or profile file (globally in /etc or on a user-by-user basis) the problem is that capistrano does not use a so-called login shell which is required to have these files loaded (which, in the end, load rbenv).
for that purpose you might want to instruct capistrano to use such a shell:
default_run_options[:shell] = '/bin/bash --login'
put that into your deploy.rb. also has the benefit of keeping you DRY by not introducing another location to manage your rbenv $PATH additions -- in contrast to fatfrog's solution.
This happens because the bashrc rbenv init doesn't get executed. Move this to the top of your deployer user bashrc file and it will fix the problem:
if [ -f /etc/bash_completion ] && ! shopt -oq posix; then
. /etc/bash_completion
fi
export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"
If your Issue is RVM on the server, then look at the help provided by rvm.io:
https://rvm.io/integration/capistrano/#gem
make sure you indeed have the rbenv installed in your server(sounds ridiculous, but it did happen in my case)
use this gem: https://github.com/yyuu/capistrano-rbenv
for more details, see my answer here: https://stackoverflow.com/a/15779928/445908
I was facing this problem and in my case the snippet from deploy/production.rb was as follows:
run "cd #{release_path} && bundle --without development test"
Had to install bundler as follows:
sudo apt-get install bundler
I'm deploying my Rails 3 app using capistrano.
I have on user (deploy) who's been added to sudoers. This is the user I'm deploying with.
When I log on to the server as deploy I have access to all of the gem commands I need .ie: bundle, whenever etc.
Capistrano seems to be running as sudo though, and when I try:
sudo whenever
I get
sudo: whenever: command not found
This means each time I try to deploy, it fails and rolls back.
I've tried setting :use_sudo to false in my deploy.rb file but still no luck
set :user, "deploy"
set :runner, user
set :use_sudo, false
Any suggestions?
Here's my complete deploy script in case there's anything in there I've missed:
require 'config/boot'
require 'hoptoad_notifier/capistrano'
require 'capistrano/ext/multistage'
require "whenever/capistrano"
#
set :whenever_command, "bundle exec whenever"
set :application, "MYAPP"
set :repository, "git#github.com:myAccount/myRepos.git"
# only keep 3 previous releases after cleanup
set :keep_releases, 3
set :scm, "git"
set :scm_user, "me"
set :branch, lambda {rails_env}
set :deploy_to, lambda {"/var/www/#{application}/#{rails_env}"}
default_run_options[:pty] = true
role :web, "xxx.xxx.xxx.xxx" # Your HTTP server, Apache/etc
role :app, "xxx.xxx.xxx.xxx" # This may be the same as your `Web` server
role :db, "xxx.xxx.xxx.xxx", :primary => true # This is where Rails migrations will run
set :user, "deploy"
set :runner, user
set :use_sudo, false
ssh_options[:paranoid] = false
ssh_options[:port] = 22
namespace :deploy do
task :start do ; end
task :stop do ; end
task :restart, :roles => :app do
run " touch #{File.join(current_path,'tmp','restart.txt')}"
end
end
namespace :bundle do
desc "run bundle install"
task :install do
run "cd #{current_release} && bundle install"
end
end
namespace :tail do
desc "Tail the current environment's log file"
task :log, :roles => :app do
stream "tail -f #{shared_path}/log/#{rails_env}.log"
end
desc "Tail the new relic log file"
task :new_relic, :roles => :app do
stream "tail -f #{shared_path}/log/new_relic.log"
end
end
before "deploy:restart", "bundle:install"
after "deploy:restart", "deploy:cleanup"
after "deploy:restart", "whenever:update_crontab"
on server run which whenever or whereis whenever you should get full path to the command put it into script:
set :whenever_command, "path_to-whenever"
It's not clean solution but might work.
Another solution might be sudo reconfiguration, go to /etc/sudoers and have a look on env_keep adding PATH might have been important, to keep all the stuff important for application you could use rvm, capistrano-rvm integration and put all the displayed variables from rvm info to env_keep, theoreticaly it should work, just be careful to not mess anything
I am new to using git and Capistrano. I have setup everything else on my server and pushed my app onto a git repo (http://github.com/tnederlof/daily-trailer). When I go to run cap deploy:cold everything seems to be working until it tries to rake the db. Below is what I get when I run it, this is the last bunch of information I recieve and where the error occurs:
* executing "cd /var/www/dailytrailer.net/releases/20100205052047; rake RAILS_ENV=production db:migrate"
servers: ["173.203.201.168"]
[173.203.201.168] executing command
** [out :: 173.203.201.168] (in /var/www/dailytrailer.net/releases/20100205052047)
command finished
* executing `deploy:start'
[DEPRECATED] `deploy:start` is going to be removed after 2.5.9 - see http://is.gd/2BPeA
* executing "cd /var/www/dailytrailer.net/current && nohup script/spin"
servers: ["173.203.201.168"]
[173.203.201.168] executing command
** [out :: 173.203.201.168] nohup: ignoring input and appending output to `nohup.out'
** [out :: 173.203.201.168] nohup: cannot run command `script/spin': No such file or directory
command finished
failed: "sh -c 'cd /var/www/dailytrailer.net/current && nohup script/spin'" on 173.203.201.168
Can someone please help me figure out what script/spin is all about?
Thank you!
Do you know what you're trying to use for an app server? If it's Passenger, then you've got something screwed up in your deploy.rb. (Post that file if you want more help debugging this.) If it's mongrel, then this should be helpful.
http://www.rubyrobot.org/article/deploying-rails-20-to-mongrel-with-capistrano-21
so I am having the sam problem here
Everything gets executed expect for
executing `deploy:start'
[DEPRECATED] `deploy:start` is going to be removed after 2.5.9 - see http://is.gd/2BPeA
* executing "cd /srv/www/domain.com/domain/current && nohup script/spin"
servers: ["domain.com"]
[domain.com] executing command
** [out :: domain.com] nohup: ignoring input and appending output to `nohup.out'
** [out :: domain.com] nohup: cannot run command `script/spin': No such file or directory
command finished
failed: "sh -c 'cd /srv/www/domain.com/domain/current && nohup script/spin'" on domain.com
here is my deploy file don't see any problems as is
set :application, "domain"
set :repository, "git#git.assembla.com:domain.git"
set :user, "blitz"
set :use_sudo, false
set :scm, :git
# Or: `accurev`, `bzr`, `cvs`, `darcs`, `git`, `mercurial`, `perforce`, `subversion` or `none`
set :deploy_to, "/srv/www/domain.com/#{application}"
#set :git_enable_submodules, 1 # Make sure git submodules are populated
set :port, 3002 # The port you've setup in the SSH setup section
#set :ssh_options, { :forward_agent => true }
default_run_options[:pty] = true
role :web, "domain.com" # Your HTTP server, Apache/etc
role :app, "domain.com" # This may be the same as your `Web` server
role :db, "domain.com", :primary => true # This is where Rails migrations will run
#role :db, "domain.com" # for slave db
# If you are using Passenger mod_rails uncomment this:
# if you're still using the script/reapear helper you will need
# these http://github.com/rails/irs_process_scripts
namespace :deploy do
desc "Restarting mod_rails with restart.txt"
# task :start do ; end
# task :stop do ; end
task :restart, :roles => :app, :except => { :no_release => true } do
run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}"
end
desc "Make symlink for database.yml"
task :symlink_dbyaml do
run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
end
desc "Create empty database.yml in shared path"
task :create_dbyaml do
run "mkdir -p #{shared_path}/config"
put '', "#{shared_path}/config/database.yml"
end
end
after 'deploy:setup', 'deploy:create_dbyaml'
after 'deploy:update_code', 'deploy:symlink_dbyaml'
after "deploy", "deploy:cleanup"
edit:
never-mind found the ans
was using passenger and needed this in the deploy.rb
[:start, :stop].each do |t|
desc "ignore #{t} since we are using passenger"
task t do ; end
end