Capistrano deploy one server at a time - ruby-on-rails

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.

Related

Run clockwork only on one production instance (rails capistrano)

I have a production server with two instances app1 and app2 to which I use capistrano to deploy my application, ie: cap app1 deploy, cap app2 deploy.
I am now configuring the clockwork to schedule my delayed jobs. But what happens the jobs are scheduled twice, because the clockwork process runs on both app1 and app2 after application is deployed.
How can I force the capistrano to run the clockwork process only on app2 ?
Thanks for a hint.
Miroslav
SOLUTION
Add the following settings into the deploy.rb:
set :clockwork_role, :clock
And then configure only one of the instances to use the role :clock, ie:
server 'URL', user: 'deploy', roles: %w{app db web clock}
In your case you can set some config variable to true in one case, and to false in the second, and check it when setting clockwork.
But want to mention that you are using different 'stages' (which are usually 'staging', 'production', 'qa', 'features', etc) for the different servers of one stage.
Capistrano has 'roles' (app, db, background jobs, etc) each can have several servers.
Also please mention which capistrano version you're using - there were big changes from 2 to 3

Run capistrano tasks locally

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.

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

Set default stage with Capistrano 3

Is there a way to set a default stage in Capistrano 3?
I've tried putting set :stage, :production inside deploy.rb but that didn't work, it gives the error:
Stage not set, please call something such as `cap production deploy`,
where production is a stage you have defined
I only have one stage right now so I want to be able to just run cap deploy and have it execute on the default.
Capistrano v3 is somewhat of a wrapper around Rake, so you need to realize that what's really happening is that a production task is getting run first, followed by a deploy task.
If you debug it a little, you'll find that deploy.rb doesn't get loaded when you don't type in a stage. This is because the stage's task is where deploy.rb gets loaded: Looking at lib/setup.rb, a task is defined for each stage. When run, the stage's task sets :stage, loads up the capistrano defaults, and then finally loads your deploy.rb file.
So, an easy trick would be to tell Capistrano to invoke the stage task every time you run cap by adding this to the end of your Capfile (not your deploy.rb):
Rake::Task[:production].invoke
or, using the invoke method from Capistrano's DSL:
invoke :production
This may have some unintended consequences if you actually do use multiple stages, but if you only ever use the production stage, it should work fine.
Another easy solution could be a simple shell alias, such as alias cap='cap production', but it might not work great if you have multiple projects with different stage names.
After I cd into the RAILS Root directory, issuing the command:
cap development deploy
seems to work. Earlier I was in the app/models folder and issuing the command came back with this error:
Stage not set, please call something such as cap production deploy, where production is a stage you have defined.
The old solution works for me in Capistrano 3:
cap --version
#=> Capistrano Version: 3.3.5 (Rake Version: 10.4.2)
At the very top of the Capfile after these lines
# Load DSL and Setup Up Stages
require 'capistrano/setup'
add:
set :stage, :production
and then run you task as usual without the stage specified:
cap foo:bar
New answer for capistrano 3.6+:
It's better to use invoke :production unless Rake.application.options.show_tasks to avoid the warning which you would otherwise get with cap -T
You can add the following line to your deploy.rb, which will prevent Capistrano from expecting a stage:
set :stages, ["production"]

Delayed Job Capistrano task without restarting each time

How is this possible?
I am currently using Capistrano recipe that comes with delayed_job
This is what I have:
# Delayed Job recipes
require "delayed/recipes"
set :rails_env, "production" # added for delayed job
after "deploy:stop", "delayed_job:stop"
after "deploy:start", "delayed_job:start"
after "deploy:restart", "delayed_job:restart"
I don't understand very well Capistrano phases, maybe solution is to set right task to right phase.
 Update
Every time I deploy I get
executing `delayed_job:restart'
Is this really needed? Is there a way to restart delayed_job just when needed? or is it always needed?
I'm also not sure what you're looking for but maybe a simple
cap delayed_job:stop
from the command line will do? You can see all available tasks at
cap -T
UPDATE
I would argue that it is a best practice to restart your Delayed Job workers every time you deploy. In the end, the workers execute your code, and that tends to change between deploys. Now, if the code your workers run rarely changes (that includes the rails boot process, environment files, initializers, settings, models that you use, etc.) and you want to take care of this yourself, then simply remove the hooks such as
after "deploy:stop", "delayed_job:stop"
from the deploy.rb and you're fine: the dj tasks will still be at your disposal, but they will not be triggered during deploy.

Resources