I'm having some trouble deploying a rails app to a VPS using capistrano. I'm running ubuntu 10.04, rvm, rails 3.2.2, and ruby 1.9.2, nginx, and passenger.
I tried deploying a test app with no problems, then tried doing everything with an actual app in pretty much the same way and now I've run into to trouble. I ran cap deploy:setup, cap deploy:check, cap deploy:cold without any errors.
Yet when I try to access the site, I get no response. I can't access static assets either. My nginx.conf file is pointing to the 'app_name/current/public'
The production.log doesn't give any hints either. It has pretty much nothing aside from some info about the asset compiling and migrations.
So I'm stumped. I thought I did everything the same way as I did with the test app when everything went smoothly but obviously I'm forgetting something. Let me know if there's any files I can post to help diagnose the problem. Appreciate the help!
my deploy.rb:
# RVM
$:.unshift(File.expand_path('./lib', ENV['rvm_path']))
require "rvm/capistrano"
set :rvm_ruby_string, 'default'
set :rvm_type, :user
# Bundler
require "bundler/capistrano"
# General
set :application, "my_app"
set :user, "deploy_user"
set :deploy_to, "/home/#{user}/#{application}"
set :deploy_via, :copy
set :use_sudo, false
set :normalize_asset_timestamps, false
# Git
set :scm, :git
set :repository, "~/#{application}/.git"
set :branch, "master"
# VPS
role :web, "app_name.com"
role :app, "app_name.com"
role :db, "app_name.com", :primary => true
# Passenger
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
EDIT 1
nginx access.log shows lots of these:
[01/Jun/2012:11:23:11 -0400] "-" 400 0 "-" "-"
and error.log has these:
cache: [GET /] miss
EDIT 2: Not sure why but I realized I can access the assets in my app's public folder. What does it mean!?
Have you configured Nginx correctly? The virtual host's root must point to your Ruby on Rails application's public folder. The documentation for using Nginx with Phusion passenger may help. Try to examine the Nginx log files, access.log and error.log, probably they can be found in /var/log/nginx.
Related
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.
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.
This is my first rails app deploy, so please forgive me if the solution to this problem is obvious... I've been getting a 403 error (Forbidden) whenever I try to load my rails app in a browser. The deploy (using capistrano) is finally going ahead without errors, but there seems to be something wonky about my apache or passenger settings. It seems apache is trying to load an index file from the public folder rather than letting passenger intervene. I don't even get a passenger error screen when I load the app domain in a browser. I just get a Forbidden message. Has anyone else encountered the same problem?
Here's the actual error log:
[Mon Feb 27 10:03:12 2012] [error] [client xxx.xxx.xxx.xx] Directory index forbidden by Options directive: /usr/local/www/sites/project.example.ca/public/
I'm assuming this basically means it's erroring out because it can't find an index.html file, but Passenger should be intercepting it before it tries to look for an index file. So this is probably an apache error, but the virtual host is configured according to the tutorial...
I'm running rails 3.1.3, ruby 1.9.2-p290, capistrano 2.1.12, Apache 2.2, rvm 1.10.2 and whichever version of passenger would have been installed by the install script about a month ago. I followed this guide while setting up passenger: http://beginrescueend.com/integration/passenger/
Any help would be hugely appreciated! It feels like I've been trying to deploy this app FOREVER.
Here's my deploy file in case it helps:
$:.unshift(File.expand_path('./lib', ENV['rvm_path']))
require "rvm/capistrano"
set :application, "Project"
set :scm, "git"
set :repository, "ssh://git#server.project.ca/usr/local/git_root/project.git"
set :user, "deploy"
#set :rvm_bin_path, "/usr/local/rvm/bin"
set :rvm_ruby_string, "ruby-1.9.2-p290#project"
set :normalize_asset_timestamps, false
ssh_options[:forward_agent] = true
set :branch, "master"
set :deploy_via, :remote_cache
set :deploy_to, "/usr/local/www/sites/project.example.ca/public/"
set :use_sudo, false
set :domain, 'project.example.ca'
role :app, domain
role :web, domain
role :db, domain, :primary => true
We figured out the 403 error. We were deploying to /usr/local/sites/www/project.example.ca/public. However, the way capistrano deploys, the actual application was at /usr/local/sites/www/project.example.ca/public/current/public. I blew away everything already there and tweaked the deploy.rb to point to /usr/local/www/sites/project.example.ca, and changed the virtual host to point to /usr/local/sites/www/project.example.ca/current/public, and now we get a Phusion Passenger error page at least.
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
Im trying to deploy my application using Capistrano, but I get this error message:
`deploy:setup' is only run for servers matching {:except=>{:no_release=>true}}, but no servers matched
When running this command:
bundle exec cap deploy:setup
Here is my deploy.rb file.
set :application, "example.com"
set :repository, "git#github.com:username/repo.git"
set :use_sudo, false
set :scm, :git
set :web, application
set :app, application
set :db, application
set :branch, "master"
set :user, "webmaster"
set :deploy_to, "/opt/www/#{application}"
set :deploy_via, :remote_cache
set :domain, application
set :port, 2222
set :bundler_cmd, "bundle install --deployment --without=development,test"
ssh_options[:paranoid] = false
namespace :deploy do
task :start do ; end
task :stop do ; end
task :restart_stalker do
run "cd #{deploy_to}/current && thor stalker:kill && stalker:init"
end
task :restart, :roles => :app, :except => { :no_release => true } do
run "cd #{deploy_to}/current && touch tmp/restart.txt"
end
after "bundler_cmd", "deploy:restart_stalker"
end
I'm using Rails 3.
You need to define some roles. E.g.:
role :app, 'myapphostname'
role :web, 'mywebhostname'
It seems you used "set" instead of "role", but you should confirm this before making the change.
Most people are probably using multistage with capistrano so you wouldnt put your roles in the deploy.rb, so if you have added environment specific roles in config/deploy/#env_name.rb then make sure to add these in your config/deploy.rb
set :stages, %w(#env_name1, #env_name2...)
require 'capistrano/ext/multistage'
and make sure the capistrano-ext gem is installed.
Seems that you've already set up your server with bundle exec cap deploy:setup.
If that's the case you should now run bundle exec cap deploy.
I'm going to leave an answer here that helped me that when none of the suggested answers here or elsewhere could help me - I spent days researching this issue before I found a fix.
Make sure that if using multistage that the environment specific config files (e.g. config/deploy/environment.rb) are the only files in the config/deploy directory. I had an environment, dev that I was unable to deploy too, turned out there somehow was a complete empty config/deploy/dev file that was getting loaded instead of my config/deploy/dev.rb file, causing every deployment to that environment fail with the posted error.