Where is Capistrano 3's `deploy:cold` defined? - ruby-on-rails

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

Related

How can I deploy but not symlink/restart using Capistrano 3?

Capistrano v2 had two helpful tasks: cap deploy:update_code would do a full deployment to a new releases/ directory, but not change the current symlink or start/restart the server (so the server keeps running the current version without interruption). And cap deploy:update did the same thing plus changing the current symlink, but didn't start/restart the server. These were useful to shake out issues e.g. with asset compilation, before doing a real deploy.
Those two "update" tasks are gone in Capistrano v3. Is there an equivalent way to do a full deploy without changing the current symlink or restarting the server?
A custom task list this should do it:
task :deploy_without_symlink do
set(:deploying, true)
%w{ starting started
updating updated }.each do |task|
invoke "deploy:#{task}"
end
end
You can look at the code here: https://github.com/capistrano/capistrano/blob/master/lib/capistrano/tasks/framework.rake#L58 to see what deploy triggers. And the Publishing task per https://github.com/capistrano/capistrano/blob/master/lib/capistrano/tasks/deploy.rake#L38 is what changes the symlinks. So by omitting everything afterwards, you get what you are looking for.

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.

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"]

Maintaining Rails environment through multiple deployment phases

I've been using Capistrano to deploy several rails apps to a single EC2 instance. The apps are all served with Apache + Passenger. The deployment phases form most of them is as follows:
-- fetch code, stage in a "releases/[timestamp]" subdirectory of the main app directory.
-- run bundler for staged release
-- run migrations for staged release
-- run asset compilation ("assets:precompile") rake task for staged release
-- restart the delayed_job task queue processing daemon and any other background processes
-- symlink the staged release to "current" (the passenger web root)
-- restart passenger (by touching "tmp/restart" in app directory)
This is a very standard Rails deployment procedure. I've noticed that a huge bottleneck in it is loading of the rails environment for each task that requires it. For one of my larger apps, environment loading takes ~40 seconds or more and that's repeated n times for the n tasks that require the rails environment (running bundler, migrations, asset compilation, delayed_job daemon). Forgive if this is a naive question, but I was wondering if there is an easy way to load the environment only once for all of these tasks (preferably easier than consolidating the implementations of all of these tasks/jobs into a single rake task that loads the environment).
I suggest looking into vagrant for this. It's a quick and easy way to deploy. It utilizes chef for customizing the vagrant box. I think you'll want to create your own recipies (a chef thing..) to hit most of the items you've listed. Once that's done ur good to go.
Update: I ultimately concocted my own solution for this which works fine. Instead of running each of the commands that depend on the rails environment individually from the shell (using the Capistrano "run" method), I've bundled them together into a single rake task that depends on the rails environment. Where I previously ran "rake db:migrate", then "rake assets:precompile", etc., I now run a single rake task whose body includes "Rake::Task['db:migrate'].invoke" and "Rake::Task['assets:precompile'].invoke". The environment now only gets loaded once.

Capistrano deploy but manually run migrations

I'm using Capistrano to deploy a Rails application. I'm thinking of a situation where there were database changes, so I can't simply cap deploy because the migrations need to run before the code is updated. I realize there's a cap deploy:migrations, but that's a little more automatic than I'd like. I'd like to:
Push the new code to the releases directory, but not update the symlink or restart the application.
ssh into the server, run rake:db_abort_if_pending_migrations to confirm that the migrations I want to run are the only pending ones, then run rake db:migrate manually.
Complete the deploy, updating the symlink and restarting the application.
Is there any easy way to do this with the built-in Capistrano tasks, or would I need to write my own deployment steps to accomplish this?
I should mention too that I'm thinking of cases (like adding columns) where the migration can be run on a live database. For more destructive changes I realize I'd need to bring down the site with a maintenance page during the deploy.
Try:
cap deploy:update_code
Do what you described loging in to the server manually or via cap
shell
cap deploy:symlink deploy:restart
See cap -e deploy:update_code deploy:symlink deploy:restart deploy:shell for more information.
I hope this will be helpful to You.

Resources