Capistrano very slow - ruby-on-rails

I am not sure where exactly the problem is located but Capistrano takes about 5 minutes to deploy an almost empty project.
Can you tell me if I am doing something wrong or is it usual?
I am using:
Capistrano 2.9.0
Rails 3.1.3
Github Repository
not too slow server (4 cores, 1 GB memory)
ngix, passenger
Here is the output I am getting:
https://gist.github.com/1632009
Capfile
load 'deploy' if respond_to?(:namespace) # cap2 differentiator
# Uncomment if you are using Rails' asset pipeline
load 'deploy/assets'
Dir['vendor/gems/*/recipes/*.rb','vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) }
load 'config/deploy' # remove this line to skip loading any of the default tasks
deploy.rb
# -*- encoding : utf-8 -*-
require "bundler/capistrano"
set :user, 'rubys'
set :domain, 'example.com'
set :application, 'EXAMPLE'
# adjust if you are using RVM, remove if you are not
$:.unshift(File.expand_path('./lib', ENV['rvm_path']))
require "rvm/capistrano"
set :rvm_ruby_string, '1.9.2'
#set :rvm_type, :user
# file paths
set :repository, "git#github.com:GITHUBREPO/ashop.git"
set :deploy_to, "/apps/#{application}"
# using a local git repository on the server you are deploying to.
set :deploy_via, :remote_cache
set :copy_exclude, [ '.git' ]
# distribute your applications across servers (the instructions below put them
# all on the same server, defined above as 'domain', adjust as necessary)
role :app, domain
role :web, domain
role :db, domain, :primary => true
set :deploy_via, :remote_cache
set :scm, 'git'
set :branch, 'master'
set :scm_verbose, false
set :use_sudo, false
set :rails_env, :production
namespace :deploy do
desc "cause Passenger to initiate a restart"
task :restart do
run "touch #{current_path}/tmp/restart.txt"
end
end
EDIT
Networkspeed workplace:
http://www.speedtest.net/result/1714391142.png
Speed Github - Server: ~ 300KiB

Capistrano is probably slow for a bunch of reasons. One is that it opens a new remote shell to your server for every run in your deploy.rb file.
This can be amended a bit by using ssh master channels, which will cause capistrano to actually reuse ssh connections, which means less network overhead.
Here's an article on ruby deployment that mentions ssh master channels: http://alexyoung.org/2011/05/17/deployment/
Another reason is that it copies your entire codebase to a new directory for every deploy.
This is not strictly necessary when using git, and github has a wonderful article on how to "fix" this: https://github.com/blog/470-deployment-script-spring-cleaning

Related

Capistrano 3 does not update files and code in the files

I am new to Capistrano and need some help with setting it up. After I running command cap deploy it runs successfully with no errors, but it does not update anything on remote server only creates additional folders inside my_app directory with some files and also creates folder called current and placing all updates from github inside this folder. Here is my deploy.rb file
lock '3.3.3'
set :application, 'my_app'
set :repo_url, 'git#github.com:me/my_app.git'
set :branch, "master"
set :deploy_via, :remote_cache
set :user, "me"
set :stages, ["production"]
set :use_sudo, false
set :deploy_to, '/var/www/my_app'
namespace :deploy do
after :finishing, 'deploy:cleanup', "deploy:update_code"
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
What is wrong! How can I make Capistrano to update files and content of the files in my_app folder on the remote server? Thank you very much for the help!!!
Solution for this problem was simple. When you use Capistrano, you have to point your server to use folder "current". For example I use apache passenger server with rails app, so in my config file I have to specify path DocumentRoot /var/www/my_app/current/public

How to start server running Phusion Passenger

I bought some hosting space where I have SSH access. Now I want to deploy a Ruby on Rails apps which works locally to one of the subdomains I made, let's call it subdomain.mywebsite.com.
I have setup SSH access via a public key, installed Ruby on Rails and Passenger on the server, and installed Capistrano locally by following the steps provided on the website and via tutorials. When I run cap production deploy the whole site is uploaded to the production server and via SSH I can see the current, releases, repo and shared folder. Unfortunately, when I go to subdomain.mywebsite.com I get a 404 - not found error.
I am new to setting up my own server and do not know what to do now. All tutorials I have found do not explain how to continue from here, and I hope someone who reads this can help me to actually being able to access the site.
Deploy.rb:
require 'capistrano'
set :stages, ["staging", "production"]
set :default_stage, "staging"
set :application, 'chiachia_store' # application name
set :repo_url, 'git#github.com:erooijak/chiachia_store.git' # your repo url
set :deploy_to, '/home/erooijak/chiachia.erooijak.simple-webhosting.eu'
set :user, "root"
set :scm, :git
set :branch, 'master'
set :keep_releases, 5
ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp }
set :format, :pretty
set :log_level, :debug
set :pty, true
set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}
set :stage, :production
role :app, %w{root#213.159.6.126}
role :web, %w{root#213.159.6.126}
role :db, %w{root#213.159.6.126}
set :puma_rackup, -> { File.join(current_path, 'config.ru') }
set :puma_state, "#{shared_path}/tmp/pids/puma.state"
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
desc 'Copy database.yml to correct location.'
task :copy_databaseyml do
on roles(:app) do
execute :cp ,'-r', shared_path.join('config/database.yml'),
release_path.join('config/database.yml')
end
end
after :publishing, :restart
after :restart, :copy_databaseyml
end
Apache.conf:
LoadModule passenger_module /usr/lib/apache2/modules/mod_passenger.so
PassengerRoot /usr/local/rvm/gems/ruby-1.9.3-p547/gems/passenger-4.0.49
PassengerRuby /usr/bin/ruby
ServerName www.chiachia.erooijak.simple-webhosting.eu
# !!! Be sure to point DocumentRoot to 'public'!
DocumentRoot /home/erooijak/chiachia.erooijak.simple-webhosting.eu/current/public
<Directory /home/erooijak/chiachia.erooijak.simple-webhosting.eu/current/public>
# This relaxes Apache security settings.
AllowOverride all
# MultiViews must be turned off.
Options -MultiViews
# Uncomment this if you're on Apache >= 2.4
#Require all granted
</Directory>
</VirtualHost>
The effect of running this is the following:
So it kind of works. Unfortunately I get a 404 error on all domains, the PHP application keeps running properly.
The passenger.3000.log has the following information:
passenger.3000.log
html error message metnioned in log
Why don't we start from scratch.
After reading your last comments, what you want is to be able to deploy multiple rails applications on the same server.
There are many options to do that, and depending on what you choose, configuration is going to be very different. There is a good SO answer that covers the basics you might want to read:
Ruby on Rails Server options
The stack I'm used to is Nginx/capistrano/unicorn but that depends on personal preferences and the nature of what's deployed.
Apache/Phusion passenger
The first thing to do is to configure apache for your domain. The phusion passenger documentation is a very good starting point.
You can even find a complete guide on how to deploy Rails >= 3.X apps with phusion passenger in the same documentation
If you follow carefully the instructions, you should have your app up and running without puma. They even also provide you capistrano recipes to use.
Puma
At this stage, unless you app needs high concurrency, puma is not needed. Phusion Passenger is an app server by itself, no need to add puma behind it. If you really need it for some reason, then you'll be better off switching to Nginx/Puma.
I hope the references I gave you clear things up a bit.

Rails Capistrano deploy_to path

I'm trying to deploy my rails app, until now hostet at Heroku, now at DigitalOcean using Capistrano. I've created a "1-Click-Rails-Application", which creates a blank rails app, so when I open the remote server in my webbrowser, the typical rails welcome screen (index.html) shows up. When I ssh to the remote directory, the path to the rails app is:
/home/rails/
inside of the rails directory are the typical rails folders like controllers etc. So I thought that the correct deploy_to path should be:
set :deploy_to, "/home/rails/"
I've seen so many different directory suggestions that I really can't figure out what could be right. I had
set :deploy_to, "var/www/#{application}"
as well, which didn't seem to work either.
I'm glad I've managed to upload my local app to the new vpn server without any errors at all. I want to avoid using a git repo to save the extra costs for a private git repo and push it directly from my computer. The problem is, after a
cap production deploy:cold
which does a lot and runs through without any errors, doesn't seem to upload anything. At least I can't find any of "my" files on the server. Well, I'm really happy that I got this far but don't understand why my config isn't working. I hope someone can help. Here is my deploy.rb from the config directory. (I'm using rvm.)
require 'capistrano/ext/multistage'
require "bundler/capistrano"
require "rvm/capistrano"
set :application, "myApp"
set :user, "root"
set :port, 22
set :deploy_to, "home/rails/"
set :repository, "."
set :scm, :none
set :deploy_via, :copy
set :checkout, :export
set :use_sudo, false
#set :rvm_ruby_string, "ruby-2.0.0p195##{application}"
set :rvm_type, :user
set :rvm_type, :system
server "xx.xxx.xx.xx", :app, :web, :db, :primary => true
after "deploy", "deploy:migrate"
I'm using Rails 3.2.13 and Ruby 2.0.0. Thanks a lot!
Update:
I was originally following a railscast capistrano deployment tutorial to get my head around this. Thus I created the deploy folder inside the config folder with a production.rb and a staging.rb inside.
Long story short, I've found "my" rails app, inside a var/www/xx.xxx.xx.xx/current/ directory on the server. The path is specified inside the production.rb which looks like this:
server "xx.xxx.xx.xx", :app, :web, :db, :primary => true
set :deploy_to, "/var/www/xx.xxx.xx.xx"
I could now change the path above to /home/rails but the actual rails app was inside the additional folder named current. How do I have to write the path so that there is no current directory? at least not there?
set :deploy_to, "home/rails/"
The correct way is:
set :deploy_to, "/home/rails/"
and for var path:
set :deploy_to, "/var/www/#{application}"
I got this working with the latest version of Capistrano: 3.2.1 and 3.1.0
Perhaps this was fixed in a patch?
Here are the relevant parts of my files:
Gemfile:
group :development do
gem 'capistrano-rails'
end
Capfile:
require 'capistrano/setup'
# Includes default deployment tasks
require 'capistrano/deploy'
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 }
config/deploy.rb
set :deploy_to, '/var/www/wrong_stage_folder'
# make sure this value is ignored.
config/deploy/staging.rb
set :deploy_to, '/var/www/appname_stage'
config/deploy/production.rb
set :deploy_to, '/var/www/appname_prod'
Run check: cap staging deploy:check --trace
INFO [2618043b] Running /usr/bin/env mkdir -pv /var/www/appname_stage/shared /var/www/appname_stage/releases on example.server.com
Works as expected, same for production.

Missing current folder Capistrano Rails 3.2

I need to understand why capistrano doesn't create the folder current. I'm using the following command : cap deploy:setup, cap deploy:check, cap deploy
But when i check in my app directory, i don't current folder.
This my deploy.rb
# Execute "bundle install" after deploy, but only when really needed
require 'bundler/capistrano'
# Automatically precompile assets
load "deploy/assets"
# RVM integration
require "rvm/capistrano"
# Application name
set :application, "app"
# Application environment
set :rails_env, :production
# Deploy username and sudo username
set :user, "ubuntu"
default_run_options[:pty] = true
ssh_options[:forward_agent] = true
#We don't want to use sudo (root) - for security reasons
set :use_sudo, false
#Target ruby version
set :rvm_ruby_string, '1.9.3-p374'
#System-wide RVM installation
set :rvm_type, :user
#We use sudo (root) for system-wide RVM installation
set :rvm_install_with_sudo, true
#git is our SCM
set :scm, :git
#Use github repository
set :repository, "git#github.com:.../CM.git"
#master is our default git branch
set :branch, "master"
#Deploy via github
set :deploy_to, "/var/www/app/#{application}"
set :deploy_via, :remote_cache
#We have all components of the app on the same server
server "125.156.125.125", :app, :web, :db, :primary => true
namespace :deploy do
task :restart, :roles => :app, :except => { :no_release => true } do
run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}"
end
task :symlink_shared do
run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
run "ln -nfs #{shared_path}/assets #{release_path}/public/assets"
end
task :assets do
system "rsync -vr --exclude='.DS_Store' public/assets #{user}##{application}:# {shared_path}/"
end
end
after 'deploy:update_code', 'deploy:symlink_shared'
I don't understand where is the error, if someone can i help me ?
Thanks you
It could fail due to folder permissions also.
If the option
set :use_sudo, false
was not present when the first time cap was deployed, the current folder have sudo as the owner. When the user is changed, it might not have sufficient permissions to update the link.
I deleted the symbolic link and ran
cap deploy:create_symlink
This updated the symbolic link for me.
Capistrano creates a current symlink (not directory) as one of the last steps in it's deployment cycle, generally right before the application server gets sent a start/restart command. It cannot create that symlink before deploying as there is nothing to symlink to (no checkouts in /releases).
If it's still not creating the symlink, check your capistrano deploy logs for an error, it won't create the symlink if it has an error before making it to that point. And if there is an error, please post it in your question.

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