EC2 - cannot deploy as "bitnami" user - ruby-on-rails

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"]

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)

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.

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 and Git, Ruining my life. "Unable to resolve revision for [HEAD] on repository ..."

I searched all of the relevant Capistrano issues, but couldn't find something that even elucidated anything here for me.
git version 1.6.4.2
Capistrano v2.5.10
Basically, when I run my cap deploy.rb script, it connects to the server, starts executing the deploy:update task, then in the deploy:update_code task:
*** [deploy:update_code] rolling back
* executing "rm -rf /home/user_name/public_html/project_name/releases/20091223094358; true"
servers: ["project_name.com"]
It fails with the following error:
/Library/Ruby/Gems/1.8/gems/capistrano-2.5.10/lib/capistrano/recipes/deploy/scm/git.rb:231:in `query_revision': Unable to resolve revision for 'master' on repository 'ssh://git#slice_ip:path_to_git_repository'. (RuntimeError)
Here's my deploy script, I've tried including and omitting:
set :branch 'master'
I also just thought my path to the repository was off, but i've tried just about every permutation (absolute, not absolute, .git suffix, no suffix). There's definitely a bare git repository at the path i'm pointing to.
**I do have multiple projects being hosted on one slice. The other projects is also a rails project, but is running SVN. Capistrano deployments work fine.
Any pointers in the right direction or any ideas would help reduce the amount of drinking I am planning on doing if I can't figure this out. (Paths / IPs obfuscated, dont hack me bro!)
set :application, "project1"
set :user, "username"
set :repository, "ssh://git#67.24.9.133/home/git/project1.git"
set :branch, "master"
set :port, 696969
set :deploy_to, "/home/username/public_html/#{application}"
set :scm, :git
role :app, application
role :web, application
role :db, application, :primary => true
# deployment via remote client (workstation)
set :deploy_via, :copy
set :runner, user
# mod_rails
namespace :deploy do
desc "Restarting mod_rails with restart.txt"
task :restart, :roles => :app, :except => { :no_release => true } do
run "touch #{current_path}/tmp/restart.txt"
end
[:start, :stop].each do |t|
desc "#{t} task is a no-op with mod_rails"
task t, :roles => :app do ; end
end
end
This was the most relevant post (extremely relevant even), but I couldn't really figure out what they were saying the fix is. I'm pretty new with git / capistrano configs.
https://capistrano.lighthouseapp.com/projects/8716/tickets/56-query_revision-unable-to-resolve-revision-for-head-on-repository
Ok I seemed to have fixed it.
Basically, since I have 2 separate repositories on the remote server, I think the "git" user was failing because I hadn't registered an ssh keypair for the git user. That explains why one of my deploy.rb scripts was working properly, while this one wasn't.
In the link I posted in the question, one of the commenters pointed out the issue:
https://capistrano.lighthouseapp.com/projects/8716/tickets/56-query%5Frevision-unable-to-resolve-revision-for-head-on-repository
Note this error is also displayed if
you are using multiple github keys per
http://capistrano.lighthouseapp....
and you do not have these keys and a
corresponding entry in your
.ssh/config on the workstation you're
running the deploy from. so the
ls-remote is run locally. is there a
way to reference the repository at
github.com for this request while the
remote deploy uses
git#github-project1:user/project1.git
Also, see the following link for more details, since the whole ssh issue would apply even if you're not using github.
http://github.com/guides/multiple-github-accounts
Both your workstation and your server must be able to reach the repository at the address specified, if not then you may have to set :local_repository to how you access it from your workstaion, and :repository to be how your servers should access it.
For me Capistrano deployments with Git only seem to work when setting set :copy_cache, true
I've only used capistrano with git once, but never used or seen the use of ssh:// in the repository definition.
Try using set :repository, "git#67.24.9.133/home/git/project1.git" instead
Make sure the branch you are deploying from exists.
set :branch, "upgrade-to-2013.4.3"
is not equal to
set :branch, "upgrade-to-2013.3.4"

capistrano put() and upload() both failing

With capistrano, I am deploying a Rails application from Mac OS X 10.5 to CentOS 5.2
Note that deploy.rb and the server environment have not changed in over a year.
There is a task within our deploy.rb file called upload:
put(File.read( file ),"#{shared_path}/#{filename}", :via => :scp)
This fails each and every time with the following exception:
No such file or directory - /srv/ourapp/releases/20100104194410/config/database.yml
My local copy of config/database.yml is failing to upload properly. I've verified it's not our internet connection, as this happens on three different connections and two different systems.
I've also tried to swap out put() for upload() but get the same result; also, dropping :via => :scp, and/or trying to force :sftp instead similarly fails.
Relevant info:
$ cap -V
Capistrano v2.5.10
$ ruby -v
ruby 1.8.7 (2008-08-11 patchlevel 72) [i686-darwin9.6.0]
If I understand your question correctly, it sounds like Capistrano is successfully uploading the files, but Rails is failing to start because it can't find the deploy.yml file. This might be happening during the Capistrano deploy as part of the deploy:restart task, making it look like a Capistrano error.
Based on the information you've given Capistrano is uploading the file to /svr/ourapp/shared/ and Rails is almost definitely looking for it in /svr/ourapp/releases/20100104194410/config/.
If that's the case, what you'll need to do is create a task which symlinks the shared database file to the expected location then add a hook so that task will be run after finalize_update. For instance:
task :symlink_database do
run "ln -s #{shared_path}/database.yml #{latest_release}/config/database.yml"
end
after 'deploy:finalize_update', :symlink_database
namespace :deploy do
task :upload_settings, :roles => :app do
run "mkdir -p #{shared_path}/config/"
top.upload "config/database.yml", "#{shared_path}/config/database.yml", :via => :scp
end
task :symlink_yml, :roles => :app do
run "ln -sf #{shared_path}/config/database.yml #{release_path}/config/database.yml"
end
end
after 'deploy:setup', 'deploy:upload_settings'
after 'deploy:update_code', 'deploy:symlink_yml'
This is purely from a server-side view, but have you checked to make sure that the user you're using to upload has proper permissions for the directory?
Doing a recursive change for the user (or group) depending on your server environment should fix this.
chown -R user_name_here /srv/ourapp/releases/
chgrp -R group_name_here /srv/ourapp/releases/
You might also want to clean up any code repositories e.g. git gc or svn cleanup. As well as updating any symbolic links.
The "No such file or directory" error occurs when you are trying to copy a file to a destination path that does not exist. As far as I know, the put and upload methods of Capistrano merely attempt to transfer the file, but do not make the required path. Is it possible that the config/ directory, or even the shared_path itself, has not been created when you are trying to upload this file?

Resources