Set default stage with Capistrano 3
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.
Capistrano 3 don't set rails_env and stage on deploy
OMG I had
rails_env development;
insteфd
rails_env staging;
in /etc/nginx/sites-enabled/default file
How can I place capistrano stages into a sub-directory?
I was able to override some Capistrano methods to get this to work. I wrote the following code at the top of my Capfile
:
module Capistrano
module DSL
module Stages
def stages
names = Dir[stage_definitions].map { |f| "#{File.dirname(f)}/#{File.basename(f, ".rb")}".gsub("#{stage_config_path.to_s}/", '') }
assert_valid_stage_names(names)
names
end
# Override stage_definitions to include subfolders
def stage_definitions
stage_config_path.join("**/*.rb")
end
end
end
end
Explanation
By overriding the #stage_definitions
method, I added **/
to that it would look for the .rb
files in sub directories.
The next issue was that capistrano/setup.rb
had this line of code:
load stage_config_path.join("#{stage}.rb")
That means I need stage
to include the folder name. Then I overrode #stages
so that the names
variable would be an array of stages, including the subdirectory if any. Example:
config/
├── deploy/
│ ├── group_1/
| ├── ├── stage1.rb
│ ├── stage2.rb
│ ├── stage3.rb
Becomes:
['group_1/stage1', 'stage2', 'stage3']
That allows the Rake tasks to be created and load the files correctly!
$ cap group_1/stage1 deploy
How do you deploy to only one server with Capistrano v3?
As pointed out, in Capistrano 3 the way to deploy specific parts of your app to a single server is making use of HOST filtering. Let’s imagine that you are deploying directly to production and you have this configuration in config/deploy/production.rb
set :stage, :production
server "webserver1.example.com”, roles: [:web]
server "appserver1.example.com", roles: [:app]
server "appserver2.example.com", roles: [:app]
server "appserver3.example.com", roles: [:app]
server “dbserver1.example.com”, roles: [:db]
server “dbserver2.example.com”, roles: [:db]
Then if you want to deploy only to your webserver1, you just run the command:
cap --hosts=webserver1.example.com production deploy
How to add an if staging check to Capistrano task?
fetch(:stage)
is likely a symbol (it's been a while since I used capistrano). To verify this, use a more precise string representation:
execute "echo #{fetch(:stage).inspect}"
I'm betting it will print :staging
. In which case you need to do
if fetch(:stage) == :staging
Related Topics
How to Detect User Agent in Rails 3.1
Perform One Validation Only If All Other Validations Pass
How to Inherit Abstract Unit Tests in Ruby
Conditional Haml - If Else Nesting
How to Do Named Capture in Ruby
Warning: String Literal in Condition
Ruby: Merge Two Hash as One and with Value Connected
Stream and Unzip Large CSV File with Ruby
Automatic Logging of Datamapper Queries
How to Resolve Deprecation Warnings for Openssl::Cipher::Cipher#Encrypt
How to Embed Dynamic Ruby Code to "Javascript" Section in Slim Templates
Begin Rescue Not Catching Error
How to Transfer Files Using Ssh and Scp Using Ruby Calls
Is Assignment in a Conditional Clause Good Ruby Style
Ruby - Array.Join Versus String Concatenation (Efficiency)
Run a Ruby Library from the Command-Line
How to Make a Non-Blocking Request for an Exclusive Lock Using File#Flock