How to properly set up Capistrano 3 with Rails 4? - ruby-on-rails

It's 2 days what I am trying to install Capistrano 3 for a Rails 4 app, my hairs already turned grey...
The problem is that I am unable to deploy the code to server (Ubuntu 14, nginx, running on DigitalOcean).
Here's my config:
Gemfile:
gem 'capistrano', '~> 3.1.0'
gem 'capistrano-rails', '~> 1.1.0'
gem 'capistrano-bundler'
gem 'unicorn'
Capfile:
require 'capistrano/setup'
require 'capistrano/deploy'
require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
# Load custom tasks from `lib/capistrano/tasks' if you have any defined
Dir.glob('lib/capistrano/tasks/*.cap').each { |r| import r }
Dir.glob('lib/capistrano/**/*.rb').each { |r| import r }
deploy.rb:
set :application, 'project'
set :deploy_user, 'deployer'
set :scm, :git
set :repo_url, 'git#bitbucket.org:username/project.git"'
set :pty, true
set :use_sudo, false
set :keep_releases, 5
set :linked_files, %w{config/database.yml}
set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}
set(:symlinks, [
{
source: "nginx.conf",
link: "/etc/nginx/sites-enabled/#{fetch(:full_app_name)}"
},
{
source: "unicorn_init.sh",
link: "/etc/init.d/unicorn_#{fetch(:full_app_name)}"
},
{
source: "log_rotation",
link: "/etc/logrotate.d/#{fetch(:full_app_name)}"
},
{
source: "monit",
link: "/etc/monit/conf.d/#{fetch(:full_app_name)}.conf"
}
])
namespace :deploy do
before :deploy, "deploy:check_revision"
before :deploy, "deploy:run_tests"
#after 'deploy:symlink:shared', 'deploy:compile_assets_locally'
after :finishing, 'deploy:cleanup'
before 'deploy:setup_config', 'nginx:remove_default_vhost'
after 'deploy:setup_config', 'nginx:reload'
after 'deploy:setup_config', 'monit:restart'
after 'deploy:publishing', 'deploy:restart'
end
and config/deploy/production.rb:
set :stage, :production
set :branch, "master"
set :full_app_name, "#{fetch(:application)}_#{fetch(:stage)}"
set :server_name, "IP"
server 'IP', user: 'deployer', roles: %w{web app db}, primary: true
set :deploy_to, "/home/#{fetch(:deploy_user)}/apps/#{fetch(:full_app_name)}"
set :rails_env, :production
set :unicorn_worker_count, 5
set :enable_ssl, false
When I am trying to set up capistrano and run cap production deploy:setup_config, I get this output:
/Users/adam/.rvm/gems/ruby-2.0.0-p481/gems/bundler-1.6.5/lib/bundler.rb:301: warning: Insecure world writable dir /usr/local/mysql-5.6.13-osx10.7-x86_64 in PATH, mode 040777
DEBUG [d940e414] Running /usr/bin/env [ -f /etc/nginx/sites-enabled/default ] as deployer#IP
DEBUG [d940e414] Command: [ -f /etc/nginx/sites-enabled/default ]
Text will be echoed in the clear. Please install the HighLine or Termios libraries to suppress echoed text.
deployer#188.166.53.247's password: # HERE I PUT MY PASSWORD, BUT WHEN I TYPE IT, I SEE WHAT I TYPE (THE PASSWORD IS NOT HIDDEN)
DEBUG [d940e414] Finished in 28.324 seconds with exit status 0 (successful).
INFO [cba64b02] Running /usr/bin/env sudo rm /etc/nginx/sites-enabled/default as deployer#IP
DEBUG [cba64b02] Command: /usr/bin/env sudo rm /etc/nginx/sites-enabled/default
DEBUG [cba64b02] [sudo] password for deployer:
And here it stuck - nothing happened. No matter what I do (if I type something/password) -- it stuck here for over 30 minutes.
Could I ask you to help me out with this issue, guys?
Thank you very much in advance, I am not sure how to continue here.

It appears the nginx:remove_default_vhost task you have configured to run before deploy:setup_config is trying to execute rm with sudo. Capistrano 3 requires passwordless sudo to be setup, otherwise you get the symptom you have described. See the authorization section of the documentation.
Setting up the deployer user to execute rm with sudo without a password should get things moving, but before you do that I think it's worth asking: do you really want your deployer user to be able to remove arbitrary files as root without a password? It's not clear to me what the origin of that task is, but IMHO that is more a part of privisioning than of deployment and there are other tools more suited for provisioning than capistrano (chef, puppet, etc.). Or just SSH to your server and remove it. It only needs to be done once.
If you do decide to let your deployer user execute rm with sudo without a password, remember to use visudo and do not edit /etc/sudoers directly.

Related

Capistrano Production Deploy -> rbenv

I think I have set up Capistrano3 correctly on my machine and that it should be connecting to my server. When I run cap production deploy (on my machine) I receive the following error messenger:
DEBUG [2959f403] Running /usr/bin/env [ -d ~/.rbenv/versions/2.1.2 ] as [user#myIP]
DEBUG [2959f403] Command: [ -d ~/.rbenv/versions/2.1.2 ]
DEBUG [2959f403] Finished in 0.420 seconds with exit status 1 (failed).
ERROR rbenv: 2.1.2 is not installed or not found in ~/.rbenv/versions/2.1.2
(Backtrace restricted to imported tasks)
cap aborted!
SSHKit::Runner::ExecuteError: Exception while executing as [user#myIP]: exit
SystemExit: exit
Tasks: TOP => rbenv:validate
(See full trace by running task with --trace)
On my machine (iMac):
$ ruby -v
ruby 2.1.2p95
$ rbenv -v
rbenv 0.4.0
$ which rebind
/usr/local/bin/rbenv
On my server (ubuntu)
$ ruby -v
ruby 2.1.2p95
$ rbenv -v
rbenv 0.4.0-151-g83ac0fb
$ which rebind
/home/[user]/.rbenv/bin/rbenv
Any ideas how to fix this?
** More Info From Comments **
deploy.rb
# config valid only for current version of Capistrano
lock '3.4.0'
set :application, [app name]
set :repo_url, [repo location]
set :repository, [repo location]
set :scm, :git
set :deploy_user, [user]
set :user, [user]
set :use_sudo, false
set :rails_env, "production"
set :deploy_via, :copy
# setup rvm.
# how many old releases do we want to keep
set :keep_releases, 5
# files we want symlinking to specific entries in shared.
set :linked_files, %w{config/database.yml config/application.yml}
# dirs we want symlinking to shared
set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}
# what specs should be run before deployment is allowed to
# continue, see lib/capistrano/tasks/run_tests.cap
set :tests, []
# which config files should be copied by deploy:setup_config
# see documentation in lib/capistrano/tasks/setup_config.cap
# for details of operations
set(:config_files, %w(
nginx.conf
database.example.yml
log_rotation
monit
unicorn.rb
unicorn_init.sh
))
# which config files should be made executable after copying
# by deploy:setup_config
set(:executable_config_files, %w(
unicorn_init.sh
))
# files which need to be symlinked to other parts of the
# filesystem. For example nginx virtualhosts, log rotation
# init scripts etc.
set(:symlinks, [
{
source: "nginx.conf",
link: "/etc/nginx/sites-enabled/#{fetch(:full_app_name)}"
},
{
source: "unicorn_init.sh",
link: "/etc/init.d/unicorn_#{fetch(:full_app_name)}"
},
{
source: "log_rotation",
link: "/etc/logrotate.d/#{fetch(:full_app_name)}"
},
{
source: "monit",
link: "/etc/monit/conf.d/#{fetch(:full_app_name)}.conf"
}
])
namespace :deploy do
# make sure we're deploying what we think we're deploying
before :deploy, "deploy:check_revision"
# only allow a deploy with passing tests to deployed
before :deploy, "deploy:run_tests"
# compile assets locally then rsync
after :finishing, 'deploy:cleanup'
after 'deploy:publishing', 'deploy:restart'
end
Server
$ ls /home/[user]/.rbenv/versions/
[blank... ]
$
If /home/[user]/.rbenv/versions is an empty directory on the server, then you have no versions of ruby installed.
Try running rbenv install 2.1.2 on the server. You may need to install the ruby-build plugin first.

Capistrano deploy configuration

Help please to configure capistrano for deployment.
I have ssh:
user: User
host: 8.8.8.8:6554
pass: 123
Then i have bitbucket repository git#bitbucket.org:somerepo/code.git
user: Repouser#gmail.com
pass: repopass
I am just need to deploy code from default branch to User#8.8.8.8:8888:/public_html/test/ . On local machine i have ssh key, that allows me to connect without password. But capistrano didn't connect.
There is my config:
lock '3.3.5'
set :application, 'App'
set :scm, :git
set :repo_url, 'git#bitbucket.org:somerepo/code.git'
set :scm_passphrase, ""
set :scm_user, "Repouser#gmail.com"
set :user, 'User'
set :deploy_to, '/public_html/test'
set :app_dir, "/public_html/test"
set :ssh_options, {:forward_agent => true}
role :web, '8.8.8.8:6554'
namespace :deploy do
after :restart, :clear_cache do
on roles(:web), in: :groups, limit: 3, wait: 10 do
end
end
end
Error:
connection closed by remote host
** Invoke deploy:failed (first_time)
** Execute deploy:failed
Step 1: in Gemfile
gem 'capistrano'
gem 'capistrano-bundler'
gem 'capistrano-rails'
Step 2: bundle
Step 3: cap install ## it will generate set of file
Step 4: go in Capfile and paste the following code ## this file will be parallel to your rails application
require 'capistrano/setup'
require 'capistrano/deploy'
require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }
Step 5: Config/deploy.rb that will be common to both ENV
This file will be shared/common across the application environment
set :application, 'your_app' ## keep in mind that your app dir name will be your_app
set :repo_url, 'git#bitbucket.org:somerepo/code.git'
set :branch, 'master'
set :use_sudo, true
set :deploy_to, '/public_html/test'
set :linked_files, fetch(:linked_files, []).push('config/database.yml')
set :linked_dirs, fetch(:linked_dirs, []).push('bin', 'log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system')
namespace :deploy do
after :restart, :clear_cache do
on roles(:web), in: :groups, limit: 3, wait: 10 do
# Here we can do anything such as:
# within release_path do
# execute :rake, 'cache:clear'
# end
end
end
end
Step6: Lets create ENV specific file for now For production Environment
config/deploy/production.rb ## this file will be generate by cap install command that you did earlier no need for this time
do comment all the code except this
role :app, %w{8.8.8.8:6554}
set :ssh_options, {
user: 'User'
}
Step 6: now do ssh to your server ssh User#8.8.8.8:6554
now it will ask for the password ... give password
Step 7: now by default your app will go /var/www/app and here you need to create the folder accordingly But in your case as you set :deploy_to, '/public_html/test' # make sure Dir name is followed by / 'Forward slash' this mistake i did many times
sudo mkdir -p /public_html
sudo mkdir -p /public_html/test
sudo chown User:User /public_html/test # `chown` will change the owner ship so that `User` user can `**Read/Write**`
umask 0002
mkdir /public_html/test/releases ## these are convention
mkdir /public_html/test/shared ## these are convention
sudo chown User:User public_html/test/releases
sudo chown User:User public_html/test/shared
mkdir .ssh
chmod .ssh 007
ssh-keygen -t rsa
and follow the step ## this will generate ssh key
cat .ssh/id_rsa.pub
Now add this key to your repo's go to => setting => deployment keys Button => click on that and add Key. Put the label name any thing you want and paste the ssh key here.
That it from server side
Step8: Now you need to add your ssh key to server
For that do cat ~/.ssh/id_rsa.pub if you have rsa key other wise generate rsa key it is very easy to crate
Step 9: Login to your server using ssh
`vi .ssh/authorized_keys` and paste your local machine rsa key
save and exit
Step 10 : cap -T ## list out all the task
step 11: cap production deploy:check
It will throw an error because database.yml file is not there
For that vi /public_html/test/shared/config/database.yml
development:
adapter: postgresql
database: testdb_cap
pool: 5
timeout: 5000
save and exit
Do again cap production deploy:check
This time would not throw any error
Step 12:
cap production deploy
And That's it
Check this also ruby rake task after deploymewnt

capistrano not using rails environment with bundler properly

I'm trying to set up Capistrano deployment for the first time and I wanted to test it on my development directory before attempting it on production. Normally I wouldn't even bother with Capistrano in the dev environment, but I'm having issues when deploying. It seems that Capistrano wants to:
A) run the bundle command: bundle --without development test
and
B) run rake assets:precompile in the development environment. I don't want that. Why would I? Maybe in the 'staging' environment if I ever wanted to do that, but certainly not in development mode.
The biggest hurdle at the moment is the fact that it bundles thinking it's in production mode and thus skips over gems which are required when it DOES correctly use the development environment when precompiling assets.
EDIT: Here's a sample of two scripts which are run - the first scripts run bundler as if we're in the production environment, and the last runs it in development environment (RAILS_ENV=development). We of course get the error because BetterErrors is a gem that's loaded only in the development environment and so it can't find BetterErrors because the call to bundle was in the production environment.
INFO [9797fc64] Running ~/.rvm/bin/rvm default do bundle install --binstubs /home/vps_user/rails_deployments/dev.www/shared/bin --path /home/vps_user/rails_deployments/dev.www/shared/bundle --without development test --deployment --quiet on localhost
DEBUG [9797fc64] Command: cd /home/vps_user/rails_deployments/dev.www/releases/20140217224858 && ~/.rvm/bin/rvm default do bundle install --binstubs /home/vps_user/rails_deployments/dev.www/shared/bin --path /home/vps_user/rails_deployments/dev.www/shared/bundle --without development test --deployment --quiet
INFO [9797fc64] Finished in 1.883 seconds with exit status 0 (successful).
DEBUG [da905ff7] Running /usr/bin/env if test ! -d /home/vps_user/rails_deployments/dev.www/releases/20140217224858; then echo "Directory does not exist '/home/vps_user/rails_deployments/dev.www/releases/20140217224858'" 1>&2; false; fi on localhost
DEBUG [da905ff7] Command: if test ! -d /home/sprvps_userucewo/rails_deployments/dev.www/releases/20140217224858; then echo "Directory does not exist '/home/vps_user/rails_deployments/dev.www/releases/20140217224858'" 1>&2; false; fi
DEBUG [da905ff7] Finished in 0.044 seconds with exit status 0 (successful).
INFO [0562438c] Running ~/.rvm/bin/rvm default do bundle exec rake assets:precompile on localhost
DEBUG [0562438c] Command: cd /home/vps_user/rails_deployments/dev.www/releases/20140217224858 && ( RAILS_ENV=development ~/.rvm/bin/rvm default do bundle exec rake assets:precompile )
DEBUG [0562438c] rake aborted!
DEBUG [0562438c] uninitialized constant BetterErrors
Is there something wrong with my setup? I'm using Capistrano v3+, with Ruby v2.1.0 inside rvm.
Gemfile:
if RUBY_PLATFORM !~ /mingw/
gem 'capistrano-rails'
gem 'capistrano-rvm'
gem 'capistrano-bundler'
end
Capfile:
# Load DSL and Setup Up Stages
require 'capistrano/setup'
# Includes default deployment tasks
require 'capistrano/deploy'
require 'capistrano/rails'
require 'capistrano/rvm'
# require 'capistrano/rbenv'
# require 'capistrano/chruby'
require 'capistrano/bundler'
# require 'capistrano/rails/assets'
# require 'capistrano/rails/migrations'
# Loads custom tasks from `lib/capistrano/tasks' if you have any defined.
Dir.glob('lib/capistrano/tasks/*.cap').each { |r| import r }
deploy.rb:
# config valid only for Capistrano 3.1
lock '3.1.0'
set :application, 'website'
set :repo_url, 'git#bitbucket.org:MyUserName/website.git'
set :user, 'vps_user'
set :tmp_dir, '/home/vps_user/tmp'
# Default value for keep_releases is 5
set :keep_releases, 3
SSHKit.config.command_map[:rake] = "bundle exec rake"
SSHKit.config.command_map[:rails] = "bundle exec rails"
# Common directories (usually assets)
set :linked_dirs, %w{ public/assets/emails public/assets/events public/assets/photographs public/assets/updates public/assets/video public/assets/wines }
namespace :deploy do
desc 'Restart application'
task :restart do
on roles(:app), in: :sequence, wait: 5 do
# Your restart mechanism here, for example:
execute :touch, release_path.join('tmp/restart.txt')
end
end
after :publishing, :restart
after :restart, :clear_cache do
on roles(:web), in: :groups, limit: 3, wait: 10 do
# Here we can do anything such as:
# within release_path do
# execute :rake, 'cache:clear'
# end
end
end
end
deploy/development.rb
set :branch, :develop
set :stage, :development
set :rails_env, 'development'
set :deploy_to, '/home/vps_user/rails_deployments/dev.www'
server 'localhost', user: 'vps_user', roles: %w{web app}
deploy/production.rb
set :branch, :master
set :stage, :production
set :rails_env, 'production'
set :deploy_to, '/home/vps_user/rails_deployments/www'
server 'localhost', user: 'vps_user', roles: %w{web app}
And I run the deploy command as such: bundle exec cap development deploy
OK so looking at Capistrano::Bundler under 'Usage' I saw an option in there called :bundle_without and it looked promising. So I put set :bundle_without, 'production' inside of my development.rb deploy script and it worked!
This doesn't solve the issue that Capistrano keeps trying to generate precompiled assets but I'm sure there's a solution out there like overriding the rake task or something.

Passenger standalone fails to start with capistano

I'm a bit of a newbie when it comes to deploying and related things, so please be lenient.
I'm building a staging server for a bunch of hobby projects, and to do that, I'll need to
Support multiple Ruby versions
Support multiple running rails/other applications
Support multiple databases and related software
I also want the deploy script to allow deploying to production, if the day ever comes.
This background necessitates the use of RVM, Capistrano-multistage and Passenger Standalone (the other option being Mongrel, but as I wish to use Passenger in production, I figured it'd be safer to use Passenger in staging too). All of this makes deployment a little hairy.
I've gotten things cobbled together quite nicely, and everything else seems to work, but for some reason Passenger fails to start when commanded to do so from Capistrano. If I SSH into the box and type the command in myself it works nicely. What's wrong?
To aid you in your efforts to help me, here is a copy of my config/deploy.rb
set :application, "Appname"
set :repository, "path-to-git-repo-over-ssh"
set :scm, :git
default_run_options[:pty] = true
set :rvm_ruby_string, ENV['GEM_HOME'].gsub(/.*\//,"")
set :rvm_install_ruby_params, '--1.9' # for jruby/rbx default to 1.9 mode
set :rvm_install_pkgs, %w[libyaml openssl] # package list from https://rvm.io/packages
set :rvm_install_ruby_params, '--with-opt-dir=/usr/local/rvm/usr' # package support
set :use_sudo, false
before 'deploy:setup', 'rvm:install_rvm' # install RVM
before 'deploy:setup', 'rvm:install_ruby' # install Ruby and create gemset
require "rvm/capistrano"
require "bundler/capistrano"
require 'sidekiq/capistrano'
set :deploy_via, :remote_cache
set :stages, %w(staging production)
set :default_stage, "staging"
require 'capistrano/ext/multistage'
set :rails_env, lambda { stage }
set :startcmd, lambda { "cd #{current_path} && bundle exec passenger start -d -p #{passenger_port} -e #{rails_env} --pid-file=#{current_path}/tmp/pids/passenger.#{passenger_port}.pid #{current_path}" }
namespace :deploy do
task :stop do
run("cd #{current_path} && bundle exec passenger stop -p #{passenger_port}")
end
task :restart do
run("cd #{current_path} && touch tmp/restart.txt")
end
task :start do
run("#{startcmd}")
end
end
after "deploy:update_code" do
run "(echo \"#reboot /bin/bash -l -c '#{startcmd}' >>log/boot.out 2>>log/boot.err # from capistrano \" && cat #{release_path}/crontab.#{stage}) | crontab -"
end
And here is config/deploy/staging.rb
set :deploy_to, "/var/www/appname"
set :user, 'app-specific-user'
set :password, 'super-secret-password'
set :domain, '1.2.3.4'
server domain, :app, :web
role :db, domain, :primary => true
set :passenger_port, 1234
Well bloody hell.
On complete hunch, I removed the
default_run_options[:pty] = true
Setting from the file, and like magic it started working. Now if only someone would tell me why.

gems not found on target server after Capistrano deployment

I deployed my rails 3 app onto the production server using Capistrano. The deployment is correct, the application server is correctly restarted but when I log onto the production server and go into "my_path/current", I cannot run "rails c":
The program 'rails' is currently not installed. You can install it by typing:
sudo apt-get install rails
I checked the gem list and everything seems to be correctly installed though.
My config/deploy.rb file is:
require "bundler/capistrano"
# Add RVM's lib directory to the load path.
$:.unshift(File.expand_path('./lib', ENV['rvm_path']))
# Load RVM's capistrano plugin.
require "rvm/capistrano"
set :rvm_ruby_string, '1.9.3'
set :rvm_type, :user # Don't use system-wide RVM
set :application, "MyApp"
set :repository, "git#github.com:user/myapp.git"
set :scm, :git
set :branch, "master"
set :scm_verbose, true
set :scm_username, "user" # GITHUB user name
set :user, "user" # VPS user name
set :scm_passphrase, "pass" # VPS password
set :deploy_to, "/home/luc/be"
set :use_sudo, false
server "my_server", :web, :app, :db, :primary => true
# start / stop application server
namespace :deploy do
task :start do
invoke_command "cd /home/luc/be/current; bundle exec thin start -C config/thin.config"
end
task :stop do
invoke_command "cd /home/luc/be/current; bundle exec thin stop -C config/thin.config"
end
task :restart do
invoke_command "cd /home/luc/be/current; bundle exec thin restart -C config/thin.config"
end
end
Try bundle exec rails c. Also check what error, if any, is thrown when you visit the page in your browser

Resources