Run capistrano tasks locally - ruby-on-rails

In my deploy.rb file I have a lot of tasks, one of which restarts the unicorn and some services. For example:
namespace :deploy do
task :restart do
invoke 'unicorn:restart' # using capistrano3-unicorn gem
invoke 'some_service:restart'
...
end
end
Now I need to run the same task locally through console on production server. I don't want to duplicate my code creating the same task as a rake task. I want to run this task, which is already exists and defined in the deploy.rb file, but I want to do it locally, not remotely. Is it possible ?

If I understand correctly, you have your Capistrano tasks which you run from your dev box as part of your deployment, and they execute on the server. You now want to run a specific command on the server, and you are logged into the server.
I'm not sure how to do it that way, but I'd suggest an alternative which might get you what you want. If you, on your dev box, run a specific task such as bundle exec cap production unicorn:restart, it will execute just that task on the server.

Related

Trouble with crontab and using whenever gem

Hi I am using the whenever gem and trying to send a daily email. For testing I set it to 2 minutes, and I have it in my schedule.rb file. It calls a task I have in a rake file. When I run bundle exec rake task_to_be_called, it runs and works. But the actual scheduling does not work. When I try to run things to find out crontab it says no such file or directory. Is there some way to get a crontab file, or do I make it? How do I test or get my scheduler to run that task?
EDIT: Thanks for the advice on sharing code and error.
In my lib/tasks/daily_email.rake I have
desc 'Daily email rake task test'
task daily_email_call: :environment do
ReportMailer.with(email: "email#email.com").daily_summary_report.deliver_now
end
Then in my config/schedule.rb I have
every 2.minute do
rake 'daily_email_call'
end
When I run bundle exec rake daily_email_call it functions correctly and does the send email task. My question is how to get it to do it on the schedule. I have no crontab file. Am I even able to do this locally or would it need to be on a running server. I am using windows not Linux when I run mine locally.
There is a typo in the file name,
lib/tasks/darily_email.rake => lib/tasks/daily_email.rake
I guess this is causing the error, no such file or directory

Capistrano deploy one server at a time

I am using capistrano for our RAILS deployment. We want to deploy to one server first, and after deployment is finished on the first server, then we want to start deployment on second server. We do not want restarting in sequence with delay. We want to have complete deployment one at a time. So far I have this:
namespace :deploy do
task :sequence do
on roles(:app), in: :sequence do |host|
invoke 'deploy'
end
end
end
The problem is with invoke 'deploy'
It calls deploy for all the app servers which in turns deploy in parallel.
Finally How Do I invoke deploy task for a specific host?
Following should help you to run the deploy task in sequential mode:
task :my_task, roles: :web do
find_servers_for_task(current_task).each do |server|
run "YOUR_COMMAND", hosts: server.host
end
end
If I had that requirement, I'd probably script it. You can run Capistrano with the --hosts parameter to define which of the servers you described in your stage file (config/deploy/dev|stage|prod|somethingelse.rb) you actually want to run the command against. This can take two forms. Let's say I have three servers, test1, test2, and prod1. I can run it with a list, like cap prod --hosts=test1,test2 deploy and only test1 and test2 will receive the deployment. You can also use a regular expression to achieve the same thing, like cap prod --hosts=^test deploy.
This is documented here: http://capistranorb.com/documentation/advanced-features/host-filtering/
With this in mind, I'd probably write a script (or Makefile) which runs capistrano N time, for a different server each time.

Ruby on rails: How to run a background task automatically when the server starts?

I have created a rails application that runs a background process. It pings a server periodically and displays a graph for the response time. For this I am using a gem called crono. I am starting the task from the command line using 'bundle exec crono'.
How can I run the background process automatically when the rails server starts without having to start it from the command line?
Also, is there a way to automatically refresh the page periodically so that it displays an updated graph?
Edit: This application will be deployed to production.
Edit: I still couldn't get this to work. Here's the folder structure:
application/config/
ping_job.rb
cronotab.rb
cronotab uses 'crono' gem to execute the task inside ping_job.rb every 5 seconds.
require 'typhoeus'
class PingJob
  def peform
   #task definition goes here.
  end
end
I want to run the task defined in ping_job.rb automatically when the server starts. I am thinking of using whenever gem. Any and all suggestions is welcome.
Put it in config/environment.rb right under Rails.application.initialize! this is ran to start up the rails server, so would be run after the application is initialized
Some time ago I wanted to join the start of a background process with the start of the rail server as well as you. And in the end I found out that it is the bad idea. I think the best solution is to create a deploy task that starts and restarts the process on each deploy. For example capistrano allows to do something like this:
namespace :deploy do
task :start do
invoke 'my_process:start'
end
task :stop do
invoke 'my_process:stop'
end
task :restart do
invoke 'my_process:start'
invoke 'my_process:stop'
end
end
namespace :my_process
task :start do
execute "some system command to start the process"
end
task :stop do
execute "some system command to stop the process"
end
end
Never start your process in Rails initialization files. It might start the process several times when there are few application workers on your server. Or it might start the process when you start the Rails console and so on.

Where is Capistrano 3's `deploy:cold` defined?

Capistrano on the whole is a very useful tool, but the definitions are so modular and distributed it can be difficult (or near impossible) to find the definition of a task when needed, or easily piece together the order of events.
I had only vaguely worked with Capistrano before v3, and I recall there being a "cold deploy" task.
However, I can't seem to find it anywhere within the capistrano repository, nor within any of the plugins (capistrano/rvm, capistrano/bundler, capistrano/rails, etc...). A simple repository search for the term 'cold' yields nothing
Where is this task defined? Does it exist in Capistrano v3? And is there an easy way to visualize all the tasks, in order, that run when I execute a certain command (e.g. bundle exec cap production deploy would list all 10,000+ deploy tasks)
Thanks!
actually there's no such task in capistrano 3.
You can see all task with command:
cap -T
for deploying i usually start with
cap production setup # Server setup tasks
cap production deploy:check # Check required files and directories exist
There is no such task like deploy:cold in capistrano 3 rather you can use the following command for the same thing
bundle exec cap production deploy setup
You can read the task definition in the lib files located in
lib/capistrano/tasks/deploy.rake

How to execute a command on the server with Capistrano?

I have a very simple task called update_feeds:
desc "Update feeds"
task :update_feeds do
run "cd #{release_path}"
run "script/console production"
run "FeedEntry.update_all"
end
Whenever I try to run this task, I get the following message:
[out :: mysite.com] sh: script/console: No such file or directory
I figured it's because I am not in the right directory, but trying
run "cd ~/user/mysite.com/current"
instead of
run "cd #{release_path}"
Also fails. Running the exact same commands manually (through ssh) works perfectly.
Why can't capistrano properly cd (change directory) into the site directory to run the command?
Thanks!
Update: Picked an answer, and thank you so much to all who replied.
The best answer may actually be the one on server fault, though the gist of both (the one on server fault and the one on stack overflow) is the same.
You want to use script/runner. It starts an instance of the app to execute the method you want to call. Its slow though as it has to load all of your rails app.
~/user/mysite.com/current/script/runner -e production FeedEntry.update_all 2>&1
You can run that from the capistrano task.
I cannot imagine that you would be able to remotely log into rails console from capistrano. I suggest you call your model method from a rake task.
How do I run a rake task from Capistrano?
As for the latter part of your question, are you logging into the server with the same user account as capistrano?

Resources