Capistrano has incorrect default deploy location - ruby-on-rails

I'm trying to deploy using Capistrano 3.1.0.
The file deploy.rb states:
# Default deploy_to directory is /var/www/my_app
However, when I run cap production deploy I get the following error:
mkdir: cannot create directory /var/www/shared
It appears to be ignoring my app name completely and trying to create directories in the wrong place. It should be trying to create /var/www/myapp/shared/. My deploy.rb file specifically has:
set :application, 'myapp'
Am I missing something here, or is this a bug?
UPDATE: The relevant line of the Capistrano source code appears to be:
set :deploy_to, "/var/www/#{fetch(:application)}"
in defaults.rb. If I print out the value of fetch(:application) it's nil, so something is stopping my application name from being set properly.

Turns out it's a bug with a fix that hasn't yet made it into a release.
Here's the change:
https://github.com/capistrano/capistrano/blob/master/lib/capistrano/defaults.rb#L3

Make sure you have the directory structure that Capistrano requires. You can use the Capistrano itself to create it with the command:
cap deploy:setup
Or you can create it directly with something like this:
# Capistrano will use /var/www/....... where ... is the value set in
# :application, you can override this by setting the ':deploy_to' variable
deploy_to=/var/www/:application
mkdir -p ${deploy_to}
mkdir ${deploy_to}/{releases,shared}
ref.: wiki deploy:setup and Authentication and Authorisation
edit: if you set the :deploy_to after the :application, you don't need the commit you mentioned.

Related

Capistrano deploy a rails app

I tried to deploy my Rails app, but I have some troubles because I have some folders in my repo git:
Server
API (my rails app)
Test
Hardware
How can I tell Capistrano that my rails app isn't in the / but is in /Server/API of the git folder?
I got solution from following code, you can try it.
set :application, 'app_name'
set :repo_url, 'repo_url'
set :deploy_to, 'folder_name'
set :repo_tree, "app_name" (THIS line)
I find the solution:
set :repo_tree, 'relative/path/from/your/repo'

Capistrano deploy to different path on same server

I am trying to deploy my application using capistrano. But I want to deploy my application to multiple paths of the same server.For example If for the first run I want to deploy it to below path
set :deploy_to, '/home/a/some_path/
Once completed the first one it should run for the second path that will be
set :deploy_to, '/home/b/some_path/
and so on. Any suggestions how can I achieve this? Right now my single path deployment path is working AOK.
In your config file:
set :deploy_to, ENV["DEPLOY_PATH"]
Then, to deploy, run the command setting the DEPLOY_PATH variable:
DEPLOY_PATH="my/path" cap production deploy
Using capistrano 3.8.2, I monkeypatched lib/capistrano/dsl/paths.rb in my deploy.rb, but then I found that I needed more work to get git wrapper set up right when there where different deploy users.
The result is at: https://gist.github.com/mcr/49e8c7034658120013c1fe49da77c2ac
But, I'm leaving the essence of the content here:
module Capistrano
module DSL
module Paths
def deploy_to
dir = #host.properties.fetch(:deploy_to) || fetch(:deploy_to)
puts "For #{#host.hostname} deploy_to: #{dir}"
dir
end
end
end
end
(You can take the puts out, and shorten it to a one-liner, but I found the extra debug useful)
One then does:
server "server.client1.example.com", user: "client1", roles: %w{app db web}, deploy_to: '/client1/app/foobar'
server "server.client2.example.com", user: "client2", roles: %w{app db web}, deploy_to: '/client2/app/foobar'
where server.client1.example.com and server.client2.example.com are CNAMEs or duplicate A/AAAA records for the same server. This also isolates the question of where each client is to DNS.

Cannot load configuration for Capistrano Receipe

The thing is that I want to get parameters for my Capistrano recipe from the console, so after looking on Google I came up with this:
task :set_repo do
set :repository, "git#github.com:#{configuration[:repo]}/MyApp.git"
set :scm_user, configuration[:repo]
end
When trying to run the task, I come up with a "method missing" error for the configuration hash. And after another search on Google I found that I have to load the configuration from Capistrano, so I added this code:
configuration = Capistrano::Configuration.respond_to?(:instance) ?
Capistrano::Configuration.instance(true) :
Capistrano.configuration(:must_exist)
But that's throwing a LoadError with the message "Please require this file from within a Capistrano recipe". I have tried requiring the capistrano/configuration module, but I keep getting the same error.
Any help is greatly appreciated.
Well, I found a work around without using the configuration at all.
It seems that you can set a couple of tasks outside a namespace like this
desc "Use UserA's git repository"
task :usera do
set :repository, "git#github.com:UserA/MyApp.git"
set :scm_user, "UserA"
end
desc "Use UserB's git repository"
task :userb do
set :repository, "git#github.com:UserB/MyApp.git"
set :scm_user, "UserB"
end
and after doing this, you can simply call your deploy task prepending your repository task in the console. For example:
$ cap usera deploy
So this is going to call first your usera task and then your deploy task.
You can set capistano variables from the command line.
For example, the below invocation would set the capistrano variable scm_user to 'userA' and the capistrano variable repository to "http://myrepo.com/blah":
cap deploy -s scm_user="userA" -s repository="http://myrepo.com/blah"
This has the same effect as putting
set :scm_user, 'userA'
set :repository, 'http://myrepo.com/blah'
at the top of your deploy.rb file.

Can a specify a particular server on the capistrano command line?

I just tried to run
cap deploy:setup
on the command line, but it wanted it to run on just one particular server instead of them all. Is there a way to run a task on just one server from the command line, or do I have to define it that way in the deploy.rb file?
Are you using capistrano-multistage? If not I recommend you do, I believe you can achieve the same with just the deploy.rb but personally I just find it easier this way and it makes this process much neater, especially if you start doing different things in production, staging or other stages.
Basically once you've installed the gem locally you can simply run commands like this:
cap staging deploy:setup
Where the 'staging' part matches one of you stage files (See below).
To get up and running change deploy.rb to something like this:
set :stages, %w(staging production)
set :default_stage, "staging"
require 'capistrano/ext/multistage'
after "deploy", "deploy:cleanup"
Then add a folder named deploy into the config directory of your rails app. In there you can place your separate deployment files, e.g staging.rb and production.rb.

Using capistrano when remote git is on a non-standard path

My shared host did not provide git, so I built and installed it into ~/bin.
When I ran it, I got the following error on most commands, although they were successful.
stdin: is not a tty
I can solve that problem by adding:
default_run_options[:pty] = true
to my deploy.rb, but then I get this error, which blocks deployment:
sh: git: command not found
How can I resolve both errors?
I tried adding a ~/.ssh/environment file with "PATH=$PATH:$HOME/bin" (and changing sshd_config to use it) but it did nothing.
It seems whatever shell is being used by capistrano is not using the ~/.bashrc or ~/.bash_profile on the remote server.
Any ideas how to set the path on the remote machine?
other info: I'm using OS X locally, and the shared server is linux on Site5.
Thanks, Chu - you put me on the right path.
just using: set :scm_command, "~/bin/git"
still gave me errors, since my local git is not in that place.
However, the following seems to work, and to solve my issues:
set :scm_command, "~/bin/git"
set :local_scm_command, "/usr/local/bin/git"
The problem is that you've set
default_run_options[:pty] = true
which means that your .bash_profile or your usual shell init file won't be run, which is not the case when you set it to false -- but then you'll have issues when it wants to ask you for the password.
To get around this problem, you can manually set your PATH environment variable in your deploy file:
default_environment['PATH'] = "/your/path/to/git:/and/any/other/path/you/need"
You should be able to specify the full path to git like so:
set :scm_command, "/home/your_cap_runner_user/bin/git"
I haven't tried this out for myself - found it in the documentation in the source code for git.rb in Capistrano itself.
stdin: is not a tty
This is probably because of CPanel installed on your shared host. It executes "mesg y" in global /etc/.bashrc file that is included in your ~/.bashrc one. So you can just comment-out the inclusion.
Here’s the source: http://webhostingneeds.com/Git_stdin_is_not_a_tty
A quick workaround is to set the following in your deploy.rb file:
set :deploy_via, :copy
This will cause the checkout to occur on your own machine and then be copied to the deployment server.
This is a great help, as I was running into the same issue as the original poster.
"Before" symptoms:
run cap deploy:setup (successful)
ran cap deploy:check (fails, with 'git command not found')
I now added set :scm_command, "~/bin/git" to my deploy.rb file.
ran cap deploy:setup (successful)
ran cap deploy:check (successful)
ran cap deploy:cold (fails, with the following error)
:97:in ``': No such file or directory - ~/bin/git info git#github.com:quintar/eu
reka.git -rHEAD (Errno::ENOENT)
So it looks like 'git' is recognized, but the repository I included in my deploy.rb is bypassed?
The ~/.ssh/environment file is not executed by a shell. It's a hardcoded environment file. If you want to set the path this way, you'll need to hardcode it instead of appending to $PATH. The other answers are possibly more correct, but setting ~/.ssh/environment correctly is a reliable fallback if all else fails.

Resources