GitHub Deploy via Capistrano. Public Repo and SSH works, but Private doesn't - ruby-on-rails

i really need your help. I have a Ruby on Rails Application on my local machine, a Repository at GitHub and an Ubuntu Server, which hosts the application with Nginx.
I had my repo for a lot of time public and the deployment via capistrano worked just fine. Now I converted my repo to a private one and the deployment just doesn't work. When i try to deploy it, i get the following error:
* executing `deploy'
* executing `deploy:update'
** transaction: start
* executing `deploy:update_code'
updating the cached checkout on all servers
executing locally: "git ls-remote git://github.com/GIT_USER/APPLICATION.git master"
fatal: The remote end hung up unexpectedly
*** [deploy:update_code] rolling back
* executing "rm -rf /var/www/APPLICATION/releases/DATE_OF_DEPLOY; true"
servers: ["DOMAIN"]
[DOMAIN] executing command
command finished in 424ms
So, my guess would be, that the authentication doesn't work, but it does. I copied my public key to GitHub and can even SSH there. I can SSH from the server to GitHub and it says that I am successfully authenticated. I can even see which key works. But "git ls-remote [...]" does not work and I get no info running it with trace, besides the information i already got.
So, my main problem is that i don't no where to look for the error. If you know how to solve this or can point my in any direction that would be nice.
And this is the main part of my deploy.rb:
$:.unshift(File.expand_path('./lib', ENV['rvm_path']))
require "rvm/capistrano"
require 'bundler/capistrano'
default_run_options[:pty] = true
set :user, "DEPLOY_USER"
set :domain, "DOMAIN"
set :application, "APPLICATION"
set :repository, "git#github.com:GIT_USER/APPLICATION.git"
set :deploy_to, "/var/www/#{application}"
set :deploy_via, :remote_cache
set :scm, :git
set :git_account, "GIT_USER"
set :branch, "master"
set :git_shallow_clone, 1
set :scm_verbose, true
set :use_sudo, false
set :rvm_bin_path, "/usr/local/rvm/bin"
set :rvm_ruby_string, '1.9.2'
set :rvm_type, :user # Don't use system-wide RVM
ssh_options[:port] = PORT_NUMBER
set :user, user
ssh_options[:keys] = %w(/home/DEPLOY_USER/.ssh/id_rsa)
set :ssh_options, { :forward_agent => true}
server domain, :app, :web
# Your HTTP server, Apache/etc
role :web, domain
# This may be the same as your `Web` server
role :app, domain
# This is where Rails migrations will run
role :db, domain, :primary => true
Sorry that this thing looks so cluttered, but i tried like a thousand hints, tipps and tutorials.
Thanks for every help!
And by the Way: Yes, all the things written in Capslock are just for privacy reasons and are, of course, not the real settings I use.

I seem to remember having a similar issue with deploying using a private github repo. I don't thinkg we ever quite worked out the cause of the problem but in the end I think we solved the issue using ssh-add to add the github key to ssh-agent - might be worth a try

Since this is now a non-public repo, you should be using git#... address.
I see you have this in your deploy.rb file, but ls-remote is still executed on git://...
The problem may be a cached-copy of the repository you have on a server. Check if you have correct origin address in shared/cached-copy/.git/config file. You should have git#... instead of git://... there

for private repos you have to use the https style:
set :repository, "https://github.com/git_name/repo_name.git"
.. but you have to type in your username and password twice on every deploy!
so I write a little Expect-script to do that for me
have a look at this gist
.. or as a walkthrough:
1 - make a file in your home directory ($ cat > ~/git_cap)
#!/usr/bin/expect -f
# Expect script to supply username/password to cap deploy to git private repository
# This script needs username and password as arguments to connect to git server:
# ------------------------------------------------------------------------
# ./git_cap gituser gitpwd
# -------------------------------------------------------------------------
# set Variables
set g_user [lrange $argv 0 0]
set g_pwd [lrange $argv 1 1]
set timeout -1
spawn cap deploy
match_max 100000
# Look for user prompt
expect "*?sername:*"
send -- "$g_user\r"
send -- "\r"
# Look for passwod prompt
expect "*?assword:*"
send -- "$g_pwd\r"
send -- "\r"
# Look for user prompt
expect "*?sername:*"
send -- "$g_user\r"
send -- "\r"
# Look for passwod prompt
expect "*?assword:*"
send -- "$g_pwd\r"
send -- "\r"
expect eof
2 - make it executable
$ chmod 755 ~/git_cap
$ chmod +x ~/git_cap
3 - add a alias in your .profile / .bashrc .. (optional)
alias gcap='~/git_cap gitname gitpwd'
4 - add your sudo-pwd to deploy.rb or extend the expect-script for sudo-pwd
( for that reason username & password expected 2 times, even if it where possible to use it more times .. but this way you can add a line for password with exp_continue so every next password will send the sudo-pwd and not your git-pwd)
5 - deploy with gcap
rails_root$ gcap

Related

Deployment issue using Mina to deploy Rails5 app. Hangs on updating Symlink

After a mina deploy, it's hanging on "Updating the /home/x/app/current symlink". No errors. It just sits there.
I have tried removing the app directory from the server and "mina setup", but still encountering the same problem. I had no issues deploying initially, but it seems any attempt to deploy subsequent releases results in this problem.
I initially followed this guide to deploy: https://www.ralfebert.de/tutorials/rails-deployment/
require 'mina/rails'
require 'mina/git'
require 'mina/rvm'
# Basic settings:
# domain - The hostname to SSH to.
# deploy_to - Path to deploy into.
# repository - Git repo to clone from. (needed by mina/git)
# branch - Branch name to deploy. (needed by mina/git)
set :application_name, 'x'
set :domain, 'x'
set :user, fetch(:application_name)
set :deploy_to, "/home/#{fetch(:user)}/app"
set :repository, 'x'
set :branch, 'x'
set :rvm_use_path, '/etc/profile.d/rvm.sh'
# Optional settings:
# set :user, 'foobar' # Username in the server to SSH to.
# set :port, '30000' # SSH port number.
# set :forward_agent, true # SSH forward_agent.
# shared dirs and files will be symlinked into the app-folder by the 'deploy:link_shared_paths' step.
# set :shared_dirs, fetch(:shared_dirs, []).push('somedir')
set :shared_files, fetch(:shared_files, []).push('config/database.yml', 'config/secrets.yml')
# This task is the environment that is loaded for all remote run commands, such as
# `mina deploy` or `mina rake`.
task :environment do
ruby_version = File.read('.ruby-version').strip
raise "Couldn't determine Ruby version: Do you have a file .ruby-version in your project root?" if ruby_version.empty?
invoke :'rvm:use', ruby_version
end
task :setup do
in_path(fetch(:shared_path)) do
command %[mkdir -p config]
# Create database.yml for Postgres if it doesn't exist
path_database_yml = "config/database.yml"
database_yml = %[production:
database: #{fetch(:user)}
adapter: postgresql
pool: 5
timeout: 5000]
command %[test -e #{path_database_yml} || echo "#{database_yml}" > #{path_database_yml}]
# Create secrets.yml if it doesn't exist
path_secrets_yml = "config/secrets.yml"
secrets_yml = %[production:\n secret_key_base:\n #{`rake secret`.strip}]
command %[test -e #{path_secrets_yml} || echo "#{secrets_yml}" > #{path_secrets_yml}]
# Remove others-permission for config directory
command %[chmod -R o-rwx config]
end
end
desc "Deploys the current version to the server."
task :deploy do
# uncomment this line to make sure you pushed your local branch to the remote origin
# invoke :'git:ensure_pushed'
deploy do
# Put things that will set up an empty directory into a fully set-up
# instance of your project.
invoke :'git:clone'
invoke :'deploy:link_shared_paths'
invoke :'bundle:install'
# invoke :'rails:db_migrate'
invoke :'rails:assets_precompile'
invoke :'deploy:cleanup'
on :launch do
command "sudo service #{fetch(:user)} restart"
end
end
# you can use `run :local` to run tasks on local machine before of after the deploy scripts
# run(:local){ say 'done' }
end
# For help in making your deploy script, see the Mina documentation:
#
# - https://github.com/mina-deploy/mina/tree/master/docs
I used the same great tutorial, got the same problem.
You can run mina deploy --verbose to see where it stuck.
For me it was not the symlink updating, but sudo service rails-demo restart command.
I used sudo visudo on the server and put the following line there:
rails-demo ALL=(ALL) NOPASSWD: /usr/sbin/service rails-demo restart
Now it works like a charm.
Good luck!

Deploying Rails App with Capistrano - "ERROR: Repository not found."

I'm having trouble using Capistrano to deploy a Rails app to an EC2 instance. I am developing the new app for my work on my personal laptop. I have two Github accounts (personal and work). I tried to add my personal public key but Github refused because my personal Github account was already associated with it. So, as a result I have two sets of private/public keys on my laptop.
I added my work public key (~/.ssh/work_rsa.pub) to my work Github account. I created a new private repository under a Github Organization (referred to as WorkOrg) that my work Github account owns (I'm an admin user in that org).
Then I had to create an alias so that git would use my work private key when pushing to Github. Here's how my ~/.ssh/config looks:
# work account
Host github.com-work
HostName github.com
User git
IdentityFile ~/.ssh/work_rsa
I then had to change the remote origin url to: git#github.com-work:WorkOrg/work_reports.git so that I could run $ git push without having to supply my username and password info every time. So, I can now push/pull just fine in this new repo (work_reports) on my laptop.
I also setup an EC2 instance (ubuntu 14.04) and created a user deploy that I can SSH into (using the same ~/.ssh/work_rsa key). I copied over my work_rsa into /home/deploy/.ssh/work_rsa so that I could push/pull from that EC2 instance.
I'm now ready to use Capistrano to setup automated deployments to my EC2 instance. When I run $ cap production deploy:check --trace it fails after this:
INFO [bb69f764] Running /usr/bin/env chmod +x /tmp/work_reports/git-ssh.sh as deploy#xx.xxx.xxx.xxx
DEBUG [bb69f764] Command: ( RBENV_ROOT=~/.rbenv RBENV_VERSION=2.2.2 /usr/bin/env chmod +x /tmp/work_reports/git-ssh.sh )
INFO [bb69f764] Finished in 0.046 seconds with exit status 0 (successful).
** Execute git:check
DEBUG [943f7c42] Running /usr/bin/env git ls-remote -h git#github.com:WorkOrg/work_reports.git as deploy#xx.xxx.xxx.xxx
DEBUG [943f7c42] Command: ( RBENV_ROOT=~/.rbenv RBENV_VERSION=2.2.2 GIT_ASKPASS=/bin/echo GIT_SSH=/tmp/work_reports/git-ssh.sh /usr/bin/env git ls-remote -h git#github.com:WorkOrg/work_reports.git )
DEBUG [943f7c42] Error: Repository not found.
DEBUG [943f7c42] fatal: Could not read from remote repository.
DEBUG [943f7c42]
DEBUG [943f7c42] Please make sure you have the correct access rights
DEBUG [943f7c42] and the repository exists.
Here's my Capfile:
require 'capistrano/setup'
require 'capistrano/deploy'
require 'capistrano/bundler'
require 'capistrano/rails'
require 'capistrano/rbenv'
set :rbenv_type, :user
set :rbenv_ruby, '2.2.2'
Here's my /config/deploy.rb file:
lock '3.2.1'
set :application, 'work_reports'
set :deploy_user, 'deploy'
set :scm, :git
#set :repo_url, 'git#github.com-work:WorkOrg/work_reports.git'
set :repo_url, 'git#github.com:WorkOrg/work_reports.git'
set :branch, ENV['REVISION'] || ENV['BRANCH'] || "master"
set :ssh_options, { forward_agent: true, paranoid: true, keys: "~/.ssh/work_rsa" }
set :deploy_to, '/home/deploy/work_reports'
set :linked_files, %w{config/database.yml}
set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}
namespace :deploy do
desc 'Restart application'
task :restart do
on roles(:app), in: :sequence, wait: 5 do
execute :touch, release_path.join('tmp/restart.txt')
end
end
after :publishing, 'deploy:restart'
after :finishing, 'deploy:cleanup'
end
And here's my /config/deploy/production.rb file:
set :stage, :production
server 'xx.xxx.xxx.xxx', user: 'deploy', roles: %w{web app db}
I even tried using the aliased remote origin url (set :repo_url, 'git#github.com-work:WorkOrg/work_reports.git') in the deploy.rb file but I got the same error.
Is there something I'm not configuring properly so that I can deploy my Rails app to EC2 using Capistrano?
I had to change my /config/deploy.rb file in order for Capistrano to actually use the work_rsa private key :
set :ssh_options, { forward_agent: false, paranoid: true, keys: "~/.ssh/work_rsa" }
Late in the train here.
My problem turned out to be changed repo name. This was fixed when I SSH'd to the server, then changed the repo URI in git config located at /to/project/repo/config.
Weird thing that this was only happening in Travis CI build. Also, no problem when I checked with capistrano-ssh-doctor.

How do I set up git in deploy.rb in a rails 4 app using mina?

I am trying to use mina to deploy my app to a digital ocean server and have a git repo on bitbucket. I was able to run mina setup' just fine, but when I runmina deploy` I get an error.
my deploy.rb
require 'mina/bundler'
require 'mina/rails'
require 'mina/git'
require 'mina/rbenv' # for rbenv support. (http://rbenv.org)
# require 'mina/rvm' # for rvm support. (http://rvm.io)
# Basic settings:
# domain - The hostname to SSH to.
# deploy_to - Path to deploy into.
# repository - Git repo to clone from. (needed by mina/git)
# branch - Branch name to deploy. (needed by mina/git)
set :rails_env, 'production'
set :domain, 'my.server'
set :deploy_to, '/home/deployer/mysite'
set :repository, 'git#bitbucket.org:me/myproject.git'
set :branch, 'master'
set :user, 'deployer'
set :forward_agent, true
set :port, '22'
# Manually create these paths in shared/ (eg: shared/config/database.yml) in your server.
# They will be linked in the 'deploy:link_shared_paths' step.
set :shared_paths, ['config/database.yml', 'log', 'config/secrets.yml']
# Optional settings:
# set :user, 'foobar' # Username in the server to SSH to.
# set :port, '30000' # SSH port number.
# This task is the environment that is loaded for most commands, such as
# `mina deploy` or `mina rake`.
task :environment do
# If you're using rbenv, use this to load the rbenv environment.
# Be sure to commit your .rbenv-version to your repository.
queue %{
echo "-----> Loading environment"
#{echo_cmd %[source ~/.bashrc]}
}
invoke :'rbenv:load'
# For those using RVM, use this to load an RVM version#gemset.
# invoke :'rvm:use[ruby-1.9.3-p125#default]'
end
# Put any custom mkdir's in here for when `mina setup` is ran.
# For Rails apps, we'll make some of the shared paths that are shared between
# all releases.
task :setup => :environment do
queue! %[mkdir -p "#{deploy_to}/shared/log"]
queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/log"]
queue! %[mkdir -p "#{deploy_to}/shared/config"]
queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/config"]
queue! %[touch "#{deploy_to}/shared/config/database.yml"]
queue %[echo "-----> Be sure to edit 'shared/config/database.yml'."]
queue! %[touch "#{deploy_to}/shared/config/secrets.yml"]
queue %[echo "-----> Be sure to edit 'shared/config/secrets.yml'."]
end
desc "Deploys the current version to the server."
task :deploy => :environment do
deploy do
# Put things that will set up an empty directory into a fully set-up
# instance of your project.
invoke :'git:clone'
invoke :'deploy:link_shared_paths'
invoke :'bundle:install'
invoke :'rails:db_migrate'
invoke :'rails:assets_precompile'
to :launch do
invoke :'passenger:restart'
end
end
end
desc "Restarts the nginx server."
task :restart do
invoke :'passenger:restart'
end
namespace :passenger do
task :restart do
queue "mkdir #{deploy_to}/current/tmp; touch #{deploy_to}/current/tmp/restart.txt"
end
end
# For help in making your deploy script, see the Mina documentation:
#
# - http://nadarei.co/mina
# - http://nadarei.co/mina/tasks
# - http://nadarei.co/mina/settings
# - http://nadarei.co/mina/helpers
When I do "mina deploy", I get this error
-----> Loading environment
-----> Loading rbenv
-----> Creating a temporary build path
-----> Cloning the Git repository
Cloning into bare repository '/home/deployer/mysite/scm'...
Host key verification failed.
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
! ERROR: Deploy failed.
-----> Cleaning up build
Unlinking current
OK
! Command failed.
Failed with status 19
I have ssh keys set up on bitbucket and Im able to push my repo to it just fine from my computer, I also have an ssh key from my server set up on bitbucket (not sure if it is needed, but I thought i would try it). What could be wrong?
add this in your deploy.rb file
set :term_mode, nil
make sure that you have added server SSH public key on github
You can use your local ssh keys for this.
Use the -A setting of SSH. and set it in mina like set :port, '22 -A' this will append the -A to the ssh command issued by Mina.
Basically it forwards the authentication you use on your deployment server. (like set :forward_agent, true does in Capistrano)
I think best practice however, is to generate a ssh key on the server and set it as a deploy key in your hosted SCM solution.
Your server tries to git from git#bitbucket.org:me/myproject.git, but there is host key at your server.
You can copy your id_rsa.pub and known_hosts file through scp command on server and then run it again. It will work.

Having problems with setting up my Capistrano with Rails

I'm trying to deploy my Rails application using Capistrano.
My deploy.rb file looks like this :
require "bundler/capistrano"
server "xx.xx.xxx.xxx", :web, :db, :primary => true
set :application, "myApp"
set :user, "ubuntu"
set :deploy_to, "/home/#{user}/apps/#{application}"
#set :deploy_via, :remote_cache
set :migrate_target, :current
set :keep_releases, 3
set :scm, "git"
set :repository, "git#github.com:name/#{application}.git"
set :branch, "master"
set :use_sudo, false
default_run_options[:pty] = true
# default_run_options[:shell] = '/bin/bash'
ssh_options[:forward_agent] = true
ssh_options[:keys] = ["#{ENV['HOME']}/.ec2/keypair.pem"]
Now whenever I try to do
cap deploy:cold
I get an error just like the following :
https://gist.github.com/c54933142b900f9f93b9
Any help would be appreciated .
The only thing I am looking at that I don't recognize is the set :migrate_target :current -- this is probably the default or implied so maybe nothing to worry about, but the root error from your gist is
** [out :: xx.xx.xxx.xxx] rm:
** [out :: xx.xx.xxx.xxx] cannot remove `/home/ubuntu/apps/myApp/current'
** [out :: xx.xx.xxx.xxx] : Is a directory
current should be a symbolic link, not a directory, so it's hard to know how it got to be directory.
I would log in to the server, change to /home/ubuntu/apps/myApp/ then rm -rf current. From there you could manually create the expected symlink (current will link to a directory whose name is a date/time), or alternatively back from your local machine run cap deploy:create_symlink then try a regular deploy.
I think it's fair to say that capistrano initialization is not it's strong suit -- once you get things going it tend to be ridiculously awesome, until then, more just infuriatingly obtuse.

capistrano deploy from one local directory to another

I want to deploy application on my local machine. For example I have my Rails APP in:
/home/thesis/dev/myapp but I want to cap deploy:setup to /home/thesis/deploy/. I have tried that but capistrano tries to connect to localhost, but it is not needed at all. How can I solve it?
Here goes my deploy.rb
role :app, "localhost"
role :web, "localhost"
role :db, "localhost", :primary => true
set(:deploy_to) { "/home/thesis/dev/myapp" }
set :bundle_without, [:development, :test]
set :use_sudo, false
set :repository, "."
set :scm, :none
set :deploy_via, :copy
set :copy_dir, "/home/thesis/deploy/tmp"
set :copy_remote_dir, "/home/thesis/deploy/tmp"
It drops with:
connection failed for: localhost (Errno::ECONNREFUSED: Connection refused - connect(2))
The localhost issue is because you're setting this in the role definitions. Since you're doing all this locally, and since Capistrano requires a role, you can set the following:
role :app, ""
I also think you're setting the copy_dir and copy_remote_dir values incorrectly. I'd recommend removing these and letting Capistrano use it's defaults.
Here's a full config which should work for you:
role :app, ""
set :use_sudo, false
set :application, 'thesis' # you'll need to specify an app name
set :repository, "."
set :scm, :none
set :deploy_to, "/home/thesis/deploy/" # the destination dir
set :deploy_via, :copy
# override deploy:restart since this isn't a Rails app
namespace :deploy do
task :restart do
# no-op
end
end
Maybe you're missing a SSH server to connect on your on machine because you only have the client installed.
Test ssh 127.0.0.1, if you still get a connection refuse error, use:
sudo apt-get install openssh-server
To install the ssh server.
I also get this problem, for I had set SSH port to 13000, not the default port 22.
And the /etc/hosts.deny added
sshd:ALL
/etc/hosts.allow added
sshd:#some allowed IPs
I processing are:
1) add to deploy.rb
ssh_options[:port] = 13600
2) add localhost to hosts.allow
sshed:127.0.0.1 localhost # others allowed IPs
You need to have an ssh server installed for local deployment to work, such as openssh (sudo apt-get install openssh-server to install)
config/deploy/staging.rb
set :stage, :staging
role :app, %w{127.0.0.1}
role :web, %w{127.0.0.1}
role :db, %w{127.0.0.1}
server '127.0.0.1', user: 'your-username', roles: %w{web app}
set :branch, "staging"
config/deploy.rb
set :deploy_to ,'/home/your/app/path/deploy'
# Path of tests to be run, use array with empty string to run all tests
set :tests, ['']
namespace :deploy do
desc "Runs test before deploying, can't deploy unless they pass"
task :run_tests do
test_log = "log/capistrano.test.log"
tests = fetch(:tests)
tests.each do |test|
puts "--> Running tests: '#{test}', please wait ..."
unless system "bundle exec rspec #{test} > #{test_log} 2>&1"
puts "--> Aborting deployment! One or more tests in '#{test}' failed. Results in: #{test_log}"
exit;
end
puts "--> '#{test}' passed"
end
puts "--> All tests passed, continuing deployment"
system "rm #{test_log}"
end
# Only allow a deploy with passing tests to be deployed
before :deploy, "deploy:run_tests"
end
Run it with with
cap staging deploy

Resources