I recently added a second database to my development Rails site, and made a custom rake task, 'SysConfig:db:migrate' which can be seen below:
namespace :SysConfig do
task :set_custom_db_config_paths do
ENV['SCHEMA'] = 'db_sysconfig/schema.rb'
Rails.application.config.paths['db'] = ['db_sysconfig']
Rails.application.config.paths['db/migrate'] = ['db_sysconfig/migrate']
Rails.application.config.paths['db/seeds'] = ['db_sysconfig/seeds.rb']
Rails.application.config.paths['config/database'] = ['config/database_sysconfig.yml']
end
namespace :db do
task :migrate => :set_custom_db_config_paths do
Rake::Task["db:migrate"].invoke
end
...
end
end
This takes all the migrations in the db_sysconfig/migrate folder and deploys them to the SysConfig database. However, I am struggling to work out how to set up this task in the deploy.rb file for Capistrano, for when I deploy to staging/production. Does anyone know how I can set the application config paths in capistrano?
Capistrano '2.15.4'
Rails '4.0.2'
Ruby '2.1.0'
I added a new task to the deploy namespace in the deploy.rb file:
namespace :deploy do
...
task :SysConfig, roles: :app do
run "cd #{current_path}; RAILS_ENV=#{rails_env} rake SysConfig:db:migrate"
end
end
after "deploy:migrate", "deploy:SysConfig"
I then set it to run after the deploy:migrate task had been ran, which caused it to successfully migrate to both databases at the same time.
Related
I need to a create a Capistrano pre-deploy step that runs a custom rake task.
in deploy.rb:
before 'deploy:starting', 'db:rollback_staging'
namespace :db do
desc 'Rollback staging db only if PR already deployed requires rollback'
task :rollback_staging do
on roles(:master) do
within current_path.to_s do
with rails_env: 'staging' do
execute :rake, 'release:rollback_staging'
end
end
end
end
end
The problem is that when deploying this code the rake task is not yet present on the server and therefore deploy fails with:
rake stdout: rake aborted!
Don't know how to build task 'release:rollback_staging' (See the list of available tasks with `rake --tasks`)
If there a way to check if the rake task exists from Capistrano?
smth like:
with rails_env: 'staging' do
execute :rake, 'release:rollback_staging' if rake_exists? 'release:rollback_staging'
end
I ended up just ignoring not 0 exit code from a rake task using raise_on_non_zero_exit: false:
with rails_env: 'staging' do
execute :rake, 'release:rollback_staging', raise_on_non_zero_exit: false
end
Would this work? Saw this pattern in https://github.com/AgileConsultingLLC/capistrano3-delayed-job
if Rake::Task.task_defined?('release:rollback_staging')
I deployed my app to vps with capistrano.
Everything works fine but only :environment task.
This is my code
namespace :deploy do
desc 'Clear memcache'
task clear_memcache: :environment do
on roles(:app) , in: :sequence, wait: 2 do
::Rails.cache.clear
CACHE.flush
end
end
after :finishing, :clear_memcache
end
But i always got this error.
#<RuntimeError: Don't know how to build task 'environment' (see --tasks)>
How can i fix this?
Thanks!
I think you are mixing two concepts. A rake task and a capistrano task. Rake tasks do use the :environment subtask, whereas the capistrano ones don't. Capistrano tasks cannot (AFAIK) directly call ruby code in the context of the rails application on the server, this is what rake tasks do.
What you actually probably want is to define both a rake task to clear the cache and a capistrano task that will call the rake task on the deployment server.
Try these:
The rake task to clear the cache:
# put this in Rakefile or any other rake file under lib/tasks
desc 'Clear memcache'
task clear_memcache: :environment do
::Rails.cache.clear
CACHE.flush
end
The capistrano task to call the rake on the server:
# config/deploy/production.rb
namespace :deploy do
desc 'Clear memcache'
task :clear_memcache do
on roles(:app) , in: :sequence, wait: 2 do
within release_path do
with rails_env: fetch(:rails_env) do
execute 'rake', 'clear_memcache'
end
end
end
end
after :finishing, :clear_memcache
end
I'm using whenever to generate the cronjobs for my Rails application.
Rails 4.2.1
In the schedule.rb I have something like that:
every 13.minutes do
rake "crons:dosomething"
end
This generates a cronjoblike this:
RAILS_ENV=production bundle exec rake crons:dosomething
Problem is that this one only runs cronjobs for production environment ... but I need the cronjob as well in test and development
I tried this:
every 13.minutes do
rake "crons:dosomething", :environment => :development
rake "crons:dosomething", :environment => :test
rake "crons:dosomething", :environment => :production
end
problem here is that the second rake runs before the first one is completely finished is there any solution for this problem?
Hello I'm writing a deploy script(rake task) for my mini project. And I have this part when I invoke the db seed :
Rake::Task['db:seed'].invoke
And also compiling assets :
Rake::Task['assets:precompile'].invoke
So I was wondering is there a way to invoke these tasks in production environment like you would do from a console like this :
RAILS_ENV=production rake db:seed
In Rails, you can do as :
[arup#app (master)]$ rails g task my_namespace my_task1
create lib/tasks/my_namespace.rake
[arup#app (master)]$ cat lib/tasks/my_namespace.rake
namespace :my_namespace do
desc "TODO"
task my_task1: :environment do
end
end
[arup#app (master)]$
Now see the Rakefile is ready for you.
Just open the Rakefile you just created, and define your tasks.
namespace :my_namespace do
task my_task1: :environment do
Rake::Task['db:seed'].invoke
Rake::Task['assets:precompile'].invoke
end
end
Hints is 2.10 Custom Rake Tasks.
I'am using Capistrano for deployment and Sidekiq for queues. I need to load user ids to set :sidekiq_queues variable in deploy.rb file to perform sidekiq queues. Now I use following code
set :sidekiq_queues, ::User.all.map {|u| "-q parsing_user_#{u.id}"}.join(" ") + " -q parsing_user_0"
but it throws following error
./config/deploy.rb:29:in `load': uninitialized constant User (NameError)
I tried to require 'rubygems' and 'active_record' into deploy.rb, but it didn't help.
In result I should have
sidekiq_queues == "-q parsing_user_1 -q parsing_user_2 -q parsing_user_3 -q parsing_user_4 -q parsing_user_5 -q parsing_user_0".
Hardcoding queue names isn't a solution.
Capistrano executes deploy.rb locally, and it doesn't load your Rails environment in deploy.rb.
It might be more trouble than it is worth. Especially if you want to execute this on your remote server, you might consider doing a Rake task instead. The => :environment in the rake task ensures that your Rails environment is loaded.
# in deploy.rb
namespace :sidekiq do
desc "Do something with queues"
task :queues, :roles => :web do
run "cd #{current_path} ; RAILS_ENV=#{rails_env} bundle exec rake sidekiq:queues"
end
end
# you'll need to decide when to execute this in your deployment process,
# something like this:
after "deploy:update_code", "sidekiq:queues"
# in lib/tasks/sidekiq.rake
namespace :sidekiq do
desc "Do something with queues"
task :queues => :environment do
queues = (User.scoped.pluck(:id) + [0]).map{|id| "-q parsing_user_#{id}"}.join(" ")
# do what you need to do
end
end