Cannot deploy an app with git to EC2 - ruby-on-rails

I have set up amazon EC2 instance (working) and Github repo (working well).
When I try to deploy the app to EC2 with using Github repo, I get this error:
** [IP] Permission denied (publickey).
** [IP] fatal: Could not read from remote repository.
**
** Please make sure you have the correct access rights
** and the repository exists.
What am I missing? I can deploy an app to EC with using copy, but not with using github.
What do I need to set up the publickey?
EDIT: SETUP
set :application, "project_name"
set :user, 'username'
set :password, "password"
set :domain, "IP.amazonaws.com"
set :deploy_to, "/path_to_directory"
set :use_sudo, false
role :web, domain
role :app, domain
role :db, domain, :primary => true
set :assets_role, [:app]
default_run_options[:pty] = true
set :repository, "git#github.com:user/repo.git"
set :scm, "git"
Thank you

You haven't set up your SSH keys between EC2 and Github correctly based on the error message, but given the information you've provided, it's not possible to provide suggestions.
Question - have you set up a deploy key on the EC2 server? I'm assuming that you are trying to deploy from the EC2 server and not your local machine using SSH Agent Forwarding. Can you do a git pull from the EC2 server to the github account? Can you ssh to git#github.com (e.g. "ssh -T git#github.com")?
The links below can help you setup a deploy key or figure out another way to manage deployment.
https://help.github.com/articles/deploying-with-capistrano
https://help.github.com/articles/managing-deploy-keys

One of the best ways to debug access privileges when beginning to use Capistrano is to try accessing your server without it.

Related

Deploying with capistrano fails - fatal: HTTP request failed. Requesting github, when set to bitbucket

So I've been deploying with Capistrano for quite some time now. Everything was good. Recently I ran into some issues.
The process was simple. I have a bitbucket account. I would push there and then cap would take the remote repo and then push it to the remote server. In doing so, upon using cap deploy I would be prompted twice for password; and actually, I don't even really know why it asked me for a password twice (so perhaps this could have some light shed on it). Nonetheless, it worked for a long time, then it randomly stopped working. Upon requesting a password the second time, it was now saying fatal: HTTP request failed.
To make matters even more confusing, I looked over the process and it's requesting a repo from a github after the second password prompt...and not bitbucket. There was a time when I used github, but that was in the past. So, I looked for a reference to the github repo in my Capfile and my deploy.rb, not finding any reference to it.
Where is this and why is it requesting it?
How can I fix this?
For reference, here is my deploy.rb (with sensitive info taken out of course):
set :application, "Application"
set :deploy_to, "/home/user/apps/app"
set :password, "webhostpassword"
set :user, "webhostuser"
set :domain, "webhostip"
set :deploy_via, :remote_cache
set :use_sudo, false
set :scm, :git
set :repository, "https://username#bitbucket.org/account/app.git"
set :scm_username, "repousername"
set :scm_passphrase, "repopassword"
ssh_options[:forward_agent] = true
role :web, domain # Your HTTP server, Apache/etc
role :app, domain # This may be the same as your 'Web' server
role :db, domain, :primary => true
default_run_options[:pty] = true
namespace :deploy do
task :start do ; end
task :stop do ; end
task :restart, :roles => :app, :except => { :no_release => true } do
run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}"
end
end
and here the output where it is failing:
servers: ["webhostip"]
[webhostip] executing command
** [webhostip :: out] Password:
Password:
** [webhostip :: out]
** [webhostip :: out] error: The requested URL returned error: 403 Forbidden
while accessing https://repo#github.com/repo/app.git/info/refs
**
** fatal: HTTP request failed
←[2;37mcommand finished in 18881ms←[0m
Notice line 6 and 7 where it is accessing github after it asks for the password (this is the second time a password prompt comes up upon using cap deploy
In my guess, capistrano will do a git pull origin <branch> instead of git clone <repo url> if the repo already exists on the remote server. Hence, it is still trying to hit github url.
You can verify this by checking the .git/config file on your remote server. or by running git remote -v command. If origin is pointing to github, change that to bitbucket. Then manually run a git pull origin master command to ensure it is working

Deploying Rails App on AWS EC2 with Capistrano

I'm trying to deploy a Rails App with Capistrano on an AWS-EC2 instance, with the default user (Ubuntu) in another user's home but it gaves me a "Permission Denied" error. This is my code:
server "9.9.9.9", :web, :app, :db, primary: true
set :application, "some_app"
set :user, "ubuntu"
set :keep_releases, 3
set :location, "9.9.9.9"
ssh_options[:keys] = ["~/Keys/serverkey.pem"]
ssh_options[:forward_agent] = true
default_run_options[:pty] = true
set :use_sudo, false
task :hello do
run "echo 'Hello World' > /home/other_user/i_was_here.txt"
end
And this is the output:
$ cap hello
* 2013-03-22 14:11:29 executing `hello'
* executing "echo 'Hello World' > /home/other_user/i_was_here.txt"
servers: ["9.9.9.9"]
[9.9.9.9] executing command
** [out :: 9.9.9.9] sh: cannot create /home/other_user/i_was_here.txt: Permission denied
command finished in 798ms
failed: "sh -c 'echo '\\''Hello World'\\'' > /home/other_user/i_was_here.txt'" on 9.9.9.9
What could be wrong? The purpose is to deploy a Rails App for another user, so I have some doubts:
Is there a way to deploy the Rails App on an AWS-EC2 instance directly with the other user?
If the answer for #1 is "no", what is the right way to deploy the Rails App with the default user Ubuntu for other users? (for no having problems with permissions in the future when the other users try to access to the apps)
In the server are managed many users because we want to get the storage and bandwidth for each user, so we did it this way and until today we are starting with Capistrano haha.
Thanks in advance.
The usual is to deploy as the user that should run/maintain the application. Otherwise you have to really be sure both users are not messing around with the permissions.
Is the reason for this scenario is that you don't want to share credentials? If so, consider using a special deploy ssh key that is added to .ssh/authorized_keys for every user.
Remove ssh_options[:forward_agent] = true line from your config file, even I had the same issue I removed this line and its working fine for me now
Thank you everyone for your answers. What I did was follow this steps and connect with Capistrano with the specific user.
http://utkarshsengar.com/2011/01/manage-multiple-accounts-on-1-amazon-ec2-instance/
The ubuntu user does not have permission to access other_user's home directory, unless sudo is used, or you change the permissions on /home/other_user.
The best approach, if you want to run the app as other_user, is to configure capistrano to deploy as other_user. You'll need to add your public ssh key to /home/other_user/.ssh/authorized_keys. If you want the app to run as ubuntu, deploy to /home/ubuntu.

Capistrano local git repository cloning to remote asks for password despite SSH keys

Totally new to Capistrano.
I have a local git repository that I want to publish to my remote server. I've followed other answers here and came up with this configuration:
require 'bundler/capistrano'
set :application, "app_name"
set :repository, '~/Dropbox/app/.git'
set :user, 'user_name'
set :deploy_to, 'ssh://remote_host/~/railsApps/app_name'
set :scm_verbose, true
set :deploy_via, :copy
default_run_options[:pty] = true
server "remote_server", :web, :app, :db, :primary => true
set :scm, :git
set :branch, "master"
ssh_options[:keys] = %w(~/.ssh/id_rsa)
after "deploy:restart", "deploy:cleanup"
This no longer asks for a password for the remote server, but fails always with the following error:
The --deployment flag requires a Gemfile.lock. Please make sure you have checked your Gemfile.lock into version control before deploying.
I am definitely including the Gemfile.lock file in my git repo.
If I change the Capistrano configuration to clone from the remote git folder to which I push (which is in that same server) then I don't get an error but it asks for my password every time I try to connect.
Help please.
Note that SSH key pairing works fine when used from the CLI for regular SSH connection.
Solution
Thanks to Tigraine I was able to solve it. In the hopes that this helps someone else, here is what finally did the trick:
Tigraine is correct in that the paths are local to the remote server, but I was getting an error when trying to use local paths, Capistrano kept searching on my local machine and throwing errors when it couldn't find those paths.
What I had to do was add the local_repository to the config and then everything worked. So the bits I changed are these:
set :local_repository, '~/Dropbox/app_name/.git'
set :repository, '~/railsApps/app_name.git'
set :deploy_to, '~/railsApps/app_name'
The local_repository path is local to my machine and the repository and deploy_to paths are local to the remote server.
First of all: Capistrano always executes it's commands on the remote server you are deploying to.
This means that all paths you use like in set :deploy_to are local paths on the server.
In my case the config looks something like this:
set :scm, 'git'
set :repository, "<repo url>"
set :branch, 'master'
set :git_shallow_clone, 1
set :scm_verbose, true
set :deploy_to, '/var/www/app'
set :deploy_via, :remote_cache
The important part here is the :deploy_to that is a local path on the server not a SSH path. This is where your config is wrong!
This gets even more important if you look at the commands capistrano then runs. It for example will usually do things like bash cd /var/www/app && bundle instal ....
If the path is not local the command will most likely fail.
Secondly this also means that Capistrano will deploy to your Git Server from your Remote Server, so you have to make sure the remote server has access to the Git Server.
The ssh_options[:keys] therefore specifies the local SSH key used to connect to that remote_server, while on the server the default key from ~/.ssh/id_rsa.pub will be used.
You can avoid having to set up your SSH key on the Server by using SSH Agent forwarding by including ssh_options[:forward_agent] = true. This will simply forward your local SSH agent socket to the server and use that (good because your key never leaves your machine)
More info on SSH Agent forwarding can be found here
Thins to check:
Check in the remote server for .ssh folder and make sure your ssh key(id_rsa.pub) is added to authorized keys with no space appended.
do ssh-add from you local folder from where you are running the cap script.
Check for the permissions of .ssh folder on remote, it should be 700 and files inside with 600 permission.
If I change the Capistrano configuration to clone from the remote git folder to which I push (which is in that same server) then I don't get an error but it asks for my password every time I try to connect.
Now clone it from the git,

Why did I have to upload my private key to my server to get Capistrano to work with GitHub?

From what I've read, including this article on GitHub itself, by using ssh agent forwarding, I should not have needed to upload my private id_rsa key to my server in order for Capistrano to connect to GitHub. Yet, until I uploaded it, cap deploy would fail trying to pull from GitHub saying "Permission denied (publickey)".
A little about my setup: My server is a shared Dreamhost server. I'm on Windows using the mysysgit Git Bash as my CLI. I previously set up passwordless ssh login to the Dreamhost server by copying my public key to authorized_keys. I can push to GitHub from my dev. Another symptom was that I could ssh into GitHub from my box, but from the server it gave the same error as above. That tipped me off about uploading my private key to resolve the issue. But it shouldn't have been necessary as I understand it.
Here's my deploy.rb:
default_run_options[:pty] = true
set :domain, "myactualdomain"
set :user, "myusernameeverywhere"
# source
set :scm, :git
set :repository, "git#github.com:#{user}/#{myreponame}.git"
set :branch, "master"
ssh_options[:forward_agent] = true
set :deploy_via, :remote_cache
set :scm_verbose, true
# deployment
set :use_sudo, false
set :deploy_to, "/home/#{user}/#{domain}"
role :web, "#{domain}"
role :app, "#{domain}"
role :db, "#{domain}", :primary => true
Why did I have to upload my private key? Is there a way to handle this where that isn't necessary?
Agent forwarding is handled by the net-ssh gem. Did you try to update it to >=1.1.0 ?

Capistrano asks for password when deploying, despite SSH keys

My ssh keys are definitely set up correctly, as I'm never prompted for the password when using ssh. But capistrano still asks for a password when deploying with cap deploy. It doesn't ask for the password when I setup with cap deploy:setup though, strangely enough. It would make the deployment cycle so much smoother without a password prompt.
Specifics: I'm deploying a Sinatra app to a Dreamhost shared account (which uses Passenger). I had followed a tutorial for doing so long back, which worked perfectly back then. Something broke since. I'm using capistrano (2.5.9) and git version 1.6.1.1. Here's my Capfile:
load 'deploy' if respond_to?(:namespace) # cap2 differentiator
set :user, 'ehsanul'
set :domain, 'jellly.com'
default_run_options[:pty] = true
# the rest should be good
set :repository, "ehsanul#jellly.com:git/jellly.git"
set :deploy_to, "/home/ehsanul/jellly.com"
set :deploy_via, :remote_cache
set :scm, 'git'
set :branch, 'deploy'
set :git_shallow_clone, 1
set :scm_verbose, true
set :use_sudo, false
server domain, :app, :web
namespace :deploy do
task :migrate do
run "cd #{current_path}; /usr/bin/rake migrate environment=production"
end
task :restart do
run "touch #{current_path}/tmp/restart.txt"
end
end
after "deploy", "deploy:migrate"
And here's the output of what happens when I cap deploy, upto the password prompt:
$ cap deploy
* executing `deploy'
* executing `deploy:update'
** transaction: start
* executing `deploy:update_code'
updating the cached checkout on all servers
executing locally: "git ls-remote ehsanul#jellly.com:git/jellly.git deploy"
/usr/local/bin/git
* executing "if [ -d /home/ehsanul/jellly.com/shared/cached-copy ]; then cd /home/ehsanul/jellly.com/shared/cached-copy && git fetch origin && git reset --hard ea744c77b0b939d5355ba2dc50ef1ec85f918d66 && git clean -d -x -f; else git clone --depth 1 ehsanul#jellly.com:git/jellly.git /home/ehsanul/jellly.com/shared/cached-copy && cd /home/ehsanul/jellly.com/shared/cached-copy && git checkout -b deploy ea744c77b0b939d5355ba2dc50ef1ec85f918d66; fi"
servers: ["jellly.com"]
[jellly.com] executing command
** [jellly.com :: out] ehsanul#jellly.com's password:
Password:
** [jellly.com :: out]
** [jellly.com :: out] remote: Counting objects: 7, done.
remote: Compressing objects: 100% (4/4), done.
What could be broken?
Executing ssh-add ~/.ssh/id_rsa in my local machine fixed the issue for me. It seemed that the ssh command line tool wasn't detecting my identity when called with Capistrano.
The password prompt is because the server you are deploying to is connecting to the git server and needs authentication. Since your local machine (where you are deploying from) already has a valid ssh-key, use that one by enabling forwarding in your Capfile:
set :ssh_options, {:forward_agent => true}
That forwards the authentication from your local machine through when the deployment server tries to connect to your git server.
This is much preferred to putting your private key out on the deployment server!
Another way of getting around the password prompt when the server is ssh'ing back on itself is to tell capistrano not to do so. Thanks to the 'readme' section for Daniel Quimper's capistrano-site5 github repo, we note the following:
set :deploy_via, :copy
Obviously, this works for the case where both the app and git repository are being hosted on the same host. But I guess some of us are doing that :)
I've had the same problem.
This line did'nt work:
set :ssh_options, {:forward_agent => true}
Then I executed mentioned on Dreamhost wiki
[local ~]$ eval `ssh-agent`
[local ~]$ ssh-add ~/.ssh/yourpublickey # omit path if using default keyname
And now I can deploy without password.
The logs show it prompted for a password after logging in via SSH to jellly.com, so it looks like the actual git update is prompting for a password.
I think this is because your repository setting specifies your git user, even though you can access it anonymously in this case.
You should create an anonymous git account and change your repo line like this:
set :repository, "git#jellly.com:git/jellly.git"
Alternatively, you could put your SSH key ON your production server, but that doesn't sound useful. You also might be able to configure SSH to forward authentication requests back through the initial SSH connection. The anonymous read-only source control for deploy is likely easier, though.
I copy and paste my local machie id_rsa.pub key to remote server authorized_key file and it worked
copying public key manually to authorized_keys did not work in my case but doing it via service worked, when I found service had simply added one more same key at the end
ssh-copy-id ~/.ssh/id_rsa.pub user#remote
If you're using a Windows workstation (portable) that you sometimes dock directly into an internal corporate network and sometimes connect via VPN, you may find that you get inconsistent behavior in running cap remote tasks asking you for a password.
In my situation, our company has login scripts that execute when you logged in while already connected to the company LAN that set your HOME directory to a network share location. If you login from cached credentials and then VPN in, your home directory isn't set by the login script. The .ssh directory that stores your private key may be in only one of those locations.
An easy fix in that situation is to just copy the .ssh directory from the HOME that has it to the one that doesn't.

Resources