Deploying Rails App on AWS EC2 with Capistrano - ruby-on-rails

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.

Related

How to set a default shell or sudo to a user in capistrano 3

I'm currently in the process of moving from Capistrano 2.x to 3.x for a rails application and running into the following issue. The general setup on the server contains a deploy user that should be the one responsible for deploying, however when a user goes to deploy, they connect to the server with their own user name.
In Capistrano 2.x, I was able to accomplish this using the default_shell option.
set :default_shell, "sudo -u deploy /bin/sh"
This does not work in Capistrano 3.x. Is there any way to either set the shell, or sudo to the deploy user in a before hook?
Things I have tried:
Setting the :default_shell option does not work as mentioned.
I tried sudo-ing to the user in a before hook. Something like sudo -s -u deploy, which works fine outside of capistrano. My user is set up for password-less sudo to the deploy user by the way. But in Capistrano it runs the command and then just hangs.
Per this SO question, it seems possible to prepend sudo -u deploy to every command, but this doesn't seem to fully work. A couple commands in, the deploy still aborts with an exception executing as my user on a Permission denied.
I can individually map some commands as SSHKit.config.command_map[:git] = 'sudo -u deploy git', but this does not seem like the best method and I do not have a list of all the commands that I would need to map.
UPDATE:
Per my third attempt, mapping all of the commands generally seems to work.
SSHKit.config.command_map = Hash.new do |hash, command|
hash[command] = "sudo -u deploy #{command}"
end
But not completely. One of the first things capistrano does is run git:check which uploads the file /tmp/git-ssh.sh. But this file gets created with my user, not the deploy user.
If you just need to change the deployment user, in capistrano 3 it's a lot easier. Assuming you have this file structure:
config
|__deploy
|__production.rb
|__staging.rb
Capfile
Then in your production.rb or staging.rb (depending on what environment you're deploying to):
set :user, 'deploy'
server 'example.com', user: fetch(:user)

Nothing happens when doing "mina setup"

I'm trying to set up Mina for deploying my Rails app. Unfortunately, when running mina setup or mina deploy, I get to the password prompt, and then nothing happens anymore.
I can manually ssh with the given user and password, so this shouldn't be a problem. But I have no idea, where mina's stuck:
josh#macbuech:~/Documents/Work/MuheimWebdesign/base (features/deployment *)$ mina deploy --verbose
base#josh.ch's password:
-----> Mina: SIGINT received.
Elapsed time: 61.00 seconds
Interestingly, yesterday it was suddenly able to connect (one of a dozen retries worded, I guess):
josh#macbuech:~/Documents/Work/MuheimWebdesign/base (features/deployment *)$ mina deploy --verbose
base#josh.ch's password:
stdin: is not a tty
jailshell: line 3: cd: /var/www/base.josh.ch: No such file or directory
! ERROR: not set up.
The path '/var/www/base.josh.ch' is not accessible on the server.
You may need to run 'mina setup' first.
! Command failed.
Failed with status 15
Then, I couldn't connect to my server anymore (neither by using mina nor plain ssh). I had to call support, and they did something that re-enabled ssh for me. Mina still doesn't work.
In config/deploy.rb, I only added set :user ... and changed :domain, :deploy_to and :repository.
set :domain, 'josh.ch'
set :user, 'base'
set :deploy_to, "/var/www/base.josh.ch"
set :repository, 'git://jmuheim/base'
set :branch, 'master'
Any idea? I'd rather not switch back to Capistrano... Thank you.
This is an old question but this is for any future Googlers that stumble across this. I had the issue described in the question, mina hanging after password entry. Looking around in the issues section of the mina git repo lead me to the fix, albeit a silly one.
In your deploy.rb file put this setting:
set :term_mode, nil
Have you tried run:
mina init
after install gem?
Can you show your deploy.rb?
I didn't have any luck with password authentication. But with public key SSH authentication, it's working fine.
HOW TO: https://www.debian-administration.org/article/530/SSH_with_authentication_key_instead_of_password

Cannot deploy an app with git to EC2

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.

EC2 - cannot deploy as "bitnami" user

I am using Capistrano for deploying a Rails app to Amazon EC2.
In the deploy files, I have following credentials for connecting to Amazon EC2:
set :user, "bitnami"
#set :user, "root"
server "ec2-XX-XXX-XXX-XX.compute-1.amazonaws.com", :app, :web, :db, :primary => true
ssh_options[:keys] = ["/Users/ada/my_amazon_ec2.pem"]
When I run cap deploy:setup and cap deploy:check, I get following:
The following dependencies failed. Please check them and try again:
--> You do not have permissions to write to `/www/myapp'. (ec2-XX-XXX-XXX-XX.compute-1.amazonaws.com)
--> You do not have permissions to write to `/www/myapp/releases'. (ec2-XX-XXX-XXX-XX.compute-1.amazonaws.com)
How's that possible? I am able to connect via SSH to EC2 as the user bitnami, but when I try it as the user root, I get the message that I should use the bitnami user for login and the connection is closed.
If I try to change in the deploy files change the bitnami user for root, the whole deployment process is ok, but then when I log in through SSH (as the bitnami user) to EC2, I don't see any files that should be deployed, the final directory is just empty.
What is wrong in this case?
Thank you so much
sudo chown -R <user> <folder path>
did the trick. The user was not the owner of the folder and hence cap check was throwing error.
Do you have the /www/myapp directory already created and does bitnami user have writing permissions there?
Let's assume your application is called "myapp123" and you want to deploy it to /opt/bitnami/apps/myapp123.
Create application directory and set proper permissions:
mkdir -p /opt/bitnami/apps/myapp123
chown -R bitnami /opt/bitnami/apps/myapp123
Add the following options to your deployment config file:
set :application, "myapp123"
set :deploy_to, "/opt/bitnami/apps/#{application}"
Are you going to use Phussion Passenger? In this case you will also need to add the following to the Capistrano config:
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
Which BitNami AMI do you use?
Bitnami stacks usually have default webroot at
/opt/bitnami/apache2/htdocs
Try writing to that folder instead (using bitnami user).
If you would like to change the webroot to another directory, you will need to create the directory and set the proper permissions, as well as tell apache you've changed the web root (click for more on how to do that).
If you are having trouble creating the directory, or applying permissions, prefix your commands with sudo like sudo mkdir www.
Do you have this:
ssh_options[:auth_methods] = ["publickey"]

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