Prevent whenenver gem from running --clear-crontab before gems installed - ruby-on-rails

I am using capistrano, and the whenever gem, on a fresh deploy to a server without the whenever gem installed, capistrano attempts to run
whenever --clear-crontab
BEFORE the rake gems:install command has been run, its clear (from this) that this command runs after deploy_code but so does my command that installs the gems (below)..
after "deploy:update_code", "deploy:symlink_config"
deploy.task :symlink_config, :roles => :app do
# create a symlink to the database.yml file located in the shared_path
run "ln -nsf #{shared_path}/config/database.yml #{current_release}/config"
# install any missing gems
run "cd #{current_release} && sudo rake gems:install --trace RAILS_ENV=#{rails_env}"
# migrate the database
run "cd #{current_release} && rake db:migrate --trace RAILS_ENV=#{rails_env}"
end
Is there a way to order these tasks, because on a cold deploy I always get whenever: not found and have to manually install the whenever gem on the remote server

What I ended up doing is removing the require "whenever/capistrano" from the config\deploy.rb to avoid the "automatic" deploy. Instead I have added a task that executes the --clear-crontab and --update-crontab. This works as it will execute in the sequence I set it to.
I have based it off this post, which deals with a slightly different problem but has the same solution - not to use the "automatic" integration with capistrano.

Related

capistrano won't run bundle install

I'm using chef and capistrano to create a server and later deploy my code. As I'm new to capistrano I took a tutorial from here and made some minor changes in order to get it going for me.
Whatever I do, I just cant get a bundler install to run on the remote server. Because of that there is no rake and the process stops at the assets:precompile. A github repo containing the code.
Am I trying something that I shouldn't do?
I fixed it with an additional task that explicitly runs bundle install. After that I still got an exception: stdout: Nothing written. I needed to add , raise_on_non_zero_exit: false
to be able to continue. Is anybody has a real test() to see if bundle install ran successfully I would be interested.
namespace :bundle do
desc "run bundle install and ensure all gem requirements are met"
task :install do
on roles(:app) do
execute "cd #{release_path} && RAILS_ENV=#{fetch(:stage)} bundle install --without=test", raise_on_non_zero_exit: false
end
end
end

Rails deployment - how do you do rake db:reset with capistrano?

I am using Linode with Ubuntu 10.04 and Capistrano, Unicorn, & Nginx to deploy.
How do I do the equivalent of heroku run rake db:reset with this setup? Is it as simple as cap deploy:cold again to run the migrations?
I've already deployed and want to drop all databases and rerun all the migrations but am not sure which commands to run with this setup to do so.
I wrote a tiny little file you can copy to run arbitrary rake tasks via capistrano: http://jessewolgamott.com/blog/2012/09/10/the-one-where-you-run-rake-commands-with-capistrano/
once setup, you can:
cap sake:invoke task="db:reset"
For Capistrano 3 without actual dropping the database. Use bundle exec cap db:reset
namespace :db do
desc 'Resets DB without create/drop'
task :reset do
on primary :db do
within release_path do
with rails_env: fetch(:stage) do
execute :rake, 'db:schema:load'
execute :rake, 'db:seed'
end
end
end
end
end
You could add the following to your deploy.rb file
namespace :custom do
task :task do
run "cd #{current_path} && bundle exec rake db:reset RAILS_ENV=#{rails_env}"
end
end
Then run cap custom:task to clear the database.
If you are using Capistrano 3, consider using the capistrano-rails-collection.
You can also use copy the code directly from db.rake file from the repository.
Or, if you want a full-fledged solution to run all your rake tasks on a remote server, check out the Cape gem.

Capistrano deploy:migrate Could not find rake-0.9.2.2 in any of the sources

My Capistrano deploy:migrate task is set to run a simple rake db:migrate command, as follows:
env PATH=/home/user/.gems/bin sh -c 'cd /home/user/app/releases/20121003140503 && rake RAILS_ENV=production db:migrate'
When I run this task during an ssh session manually it completes successfully. However when I run from my local development box, I receive the following error:
** [out :: app] Could not find rake-0.9.2.2 in any of the sources
I am able to locate my rake gem by typing which rake via ssh (/home/user/.gems/bin/rake) and rake --version gives me "rake, version 0.9.2.2," so I don't understand why this command fails via Capistrano?
Capistrano does not place bundle exec before rake command in default. If you are sure you have the rake gem in your bundle, try adding this to your deploy.rb.
set :rake, 'bundle exec rake'
This will tell Capistrano to instead of just rake run bundle exec rake. If it is in your bundle, you won't have any problems any more and you will also avoid collisions if you have more versions of rake installed on your system.
You might also just need to bundle your gems with this:
require "bundler/capistrano"
Via: Why is Capistrano not installing gems with bundler?
Once you go into your app folder, you simply type:
$bundle exec rake instead of just $rake

Missing required gems when execute cron created by whenever gem in production environment

I've ruby on rails application running in production, this apps have STOCK model and it should be updated every 1 minute.
For updating this model i create simple rake task db:populate:stocks, when it contain only two operation :
truncate the STOCK model
fill STOCK model with latest data fetch from webservice
this rake task should be execute every 1 minute, for this purpose i use whenever gem. Here my schedule.rb :
env :PATH, ENV['PATH']
set :job_template, nil
set :output, {:standard => '/home/admin/shared/log/cron.log', :error => '/home/admin/shared/log/cron-error.log'}
job_type :rake, "cd :path && rake :task RAILS_ENV=:environment --trace :output"
every 1.minute do
rake "db:populate:stocks"
end
In production i'm using rvm running ruby 1.9.2-p180, rails 3.1.0 and capistrano, here my capistrano task for update cron tab :
after "deploy:update_code" do
run "cd #{release_path} && whenever --clear-crontab RAILS_ENV=production"
run "cd #{release_path} && whenever --update-crontab RAILS_ENV=production"
end
And my schedule.rb create cron task like :
# Begin Whenever generated tasks for: RAILS_ENV=production
PATH=/home/admin/.rvm//gems/ruby-1.9.2-p180#admin/bin:/home/admin/.rvm//gems/ruby-1.9.2-p180#global/bin:/home/admin/.rvm//rubies/ruby-1.9.2-p180/bin:/home/admin/.rvm//bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
* * * * * cd /home/admin/releases/20120904103658 && RAILS_ENV=production rake db:populate:stocks --trace >> /home/admin/shared/log/cron.log 2>> /home/admin/shared/log/cron-error.log
THE PROBLEM is the cron task failed to execute the rake task, from cron-error.log :
/home/admin/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/site_ruby/1.9.1/rubygems.rb:314:in `bin_path': can't find gem rake ([">= 0"]) with executable rake (Gem::GemNotFoundException)
from /home/admin/.rvm//gems/ruby-1.9.2-p180#admin/bin/rake:19:in `<main>'
What i'm missing here, why the cron job failed to load my env ? Is there any problem with my schedule.rb ?
Make sure your RVM defaults to the correct ruby version where the gems are.
Then try to use bundle exec rake ...
by doing so it will explicitly invoke whatever the gems in the bundle (assuming you are using RVM)
I have similar problem and I fix with
rvm cron setup
in server. This add rvm env variables (PATH, GEM_HOME,GEM_PATH...) to my cronjob.
I have to delete the set command
env :PATH, ENV['PATH']
modifying PATH is not enough, check rvm help cron - there are few options that will help manage rvm in crontab.

Automatically Starting ElasticSearch with Rails

I've been doing Ruby on Rails development with ElasticSearch between two machines and its starting to get a little annoying. My usual workflow is:
git pull
bundle install
rake db:migrate (or rake db:setup depending)
rails server
elasticsearch -f -D myconfig.xml
rake environment tire:import CLASS=MyObject FORCE=true
Is there anyway I can add all of these commands to some type of start up script in Rails to bring them all into one place? It would make bringing up a dev environment a lot easier on me everytime I switch machines.
The best way I've found is to use the Foreman gem to kickstart your project and associated processes.
It looks like you should do this in your deployment using Capistrano. Here is an example config/deploy.rb file:
[basic parts omitted]
after "deploy", "bundler:bundle_install"
after "bundler:bundle_install", "db:db_migrate"
after "deploy:db_migrate", "deploy:elastic_search_indexing"
namespace :bundler do
desc 'call bundle install'
task :bundle_install do
run "cd #{deploy_to}/current && bundle install"
end
end
namespace :db do
desc 'fire the db migrations'
task :db_migrate do
run "cd #{deploy_to}/current && bundle exec rake db:migrate RAILS_ENV=\"production\""
end
end
namespace :elasticsearch do
desc 'run elasticsearch indexing via tire'
task :index_classes do
run "cd #{deploy_to}/current && bundle exec rake environment tire:import CLASS=YourObject FORCE=true "
end
end
[rest omitted]
Make sure you have a config file on the target machine (Linux) in /etc/elasticsearch/elasticsearch.yml with contents like:
cluster:
name: elasticsearch_server
network:
host: 66.98.23.12
And the last point to mention is that you should create an initializer config/initializers/tire.rb:
if Rails.env == 'production'
Tire.configure do
url "http://66.98.23.12:9200"
end
end
As you can see, this is the exact same IP address, but only used for the production environment. I assume that you access elasticsearch locally (in development mode) via localhost. elasticsearch is connection per default to
http://0.0.0.0:9200
A good starting point and also in depth help is provided by awesome Ryan Bates and his Railscasts http://railscasts.com/episodes?utf8=%E2%9C%93&search=capistrano
Whats keeping you from putting it in a bash script? And put the script inside your RAILS_APP_HOME/scripts folder?
#!/bin/sh
git pull
bundle install
rake db:migrate
rails server
elasticsearch -f -D myconfig.xml
rake environment tire:import CLASS=MyObject FORCE=true

Resources