Capistrano: trying to run rake db:seed on remote server - ruby-on-rails

I'm trying to run my seed file on a remote server using capistrano. My deploy is OK, so there is no issue there. Here is the code for running the seed file in config/deploy.rb
namespace :seed do
desc "Run a task on a remote server."
# run like: cap staging rake:invoke task=a_certain_task
task :default do
run("cd #{deploy_to}/current; /usr/bin/env bundle exec rake #{ENV['db:seed']} RAILS_ENV=#{rails_env}")
end
end
I am evoking this task by running 'cap seed'.
Whats weird is it looks like tests are running when I run this..HERE is a snippet.

Maybe the problem is with #{ENV['db:seed']} part. Isn't it should be just db:seed. The eniviroment variable db:seed doesn't exist so You are calling a pure rake command.
Try this:
run("cd #{deploy_to}/current; /usr/bin/env bundle exec rake db:seed RAILS_ENV=#{rails_env}")

Related

How to run a model method in capistrano deploy

Suppose I have a model method
def self.do_something
How do I run this method after deploy in capistrano? I've tried runner, I've tried making a rake task, nothing works. Can someone provide an exemplar?
Thanks,
kevin
You have to load the rails environment before calling your rake task in your deploy file, Capistrano doesn't do it.
run "cd #{current_path} ; RAILS_ENV=#{rails_env} bundle exec rake my:task"

How to run a rake task regularly with using CRON?

I've written a rake task for my Rails application and I'd need to run this tasks regularly with using CRON.
If I have a URL that I need to ping with CRON, I do it like this:
0 */6 * * * curl https://www.website.com/something
But how to "ping" a rake task?
The application is located in /home/deployer/apps/myapp-production/current and is running on DigitalOceal (Ubuntu server - nginx).
Thanks.
EDIT: This is my command:
0 */6 * * * cd /home/deployer/apps/myapp-production/current && RAILS_ENV=production bundle exec rake db:backup
But the output is:
/bin/sh: 1: bundle: not found
When I run just rake db:backup on my laptop (locally), everything works just well.
Do I have incorrect the path in the CRON task?
EDIT2: When I run the command cd /home/deployer/apps/myapp-production/current && RAILS_ENV=production bundle exec rake db:backup manually from the command line, everything is working, but not from the CRON.
Use whenever gem. It provides nice DSL like:
every :day, :at => '12:20am', :roles => [:app] do
rake "app_server:task"
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.

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

Capistrano deployment changing directory for migrations

I have a rails app that is not in the root directory of the repository. When it is deployed, some other static files are deployed with it in a parent directory. The structure is something like this:
root
-- otherstuff
-- railsapp
When I do a deployment with cap deploy:migrations, the Capistrano command that gets executed looks like this, which of course doesn't work:
cd /u/apps/minicart/releases/20100717215044; rake RAILS_ENV=staging db:migrate
How do I change this so that it will be:
cd /u/apps/minicart/releases/20100717215044/railsapp; rake RAILS_ENV=staging db:migrate
I made it work by adding a task that executes this command after deploy:finalize_update, but I would prefer to use the built in method, plus my hacked version is executed with every deployment.
Any advice would be appreciated.
Tim
This turned out to be very simple.
I added a deploy namepace to my deploy.rb file and then redefined the migrate method. Now my method runs on cap deploy:migrations.
namespace :deploy do
desc "Migrating the database"
task :migrate, :roles => :app do
run <<-CMD
cd #{release_path}/minicart; RAILS_ENV=#{stage} rake db:migrate
CMD
end
end

Resources