My working deployment script is failing with upload via sftp failed on XX.XXX.XXX.XXX: Net::SFTP::StatusException (Net::SFTP::StatusException write /tmp/20130610114941.tar.gz (4, "failure")) error.
here is my deployment script
require "rvm/capistrano"
require "bundler/capistrano"
set :rvm_type, :user
set :rvm_ruby_string, 'ruby-2.0.0-p0'
set :user, "deployer"
set :application, "myapp"
set :deploy_to, "/home/#{user}/apps/#{application}"
set :bundle_dir, "/home/#{user}/.rvm/gems/ruby-2.0.0-p0"
server "XX.XXX.XXX.XXX", :web, :app, :db, primary: true
set :use_sudo, false
set :deploy_via, :copy
set :repository, "."
set :copy_exclude, %w[.git log tmp .DS_Store]
set :scm, :none
default_run_options[:pty] = true
after "deploy", "deploy:cleanup" # keep only the last 5 releases
namespace :deploy do
task :start do
;
end
task :stop do
;
end
task :restart, roles: :app, except: {no_release: true} do
run "touch #{deploy_to}/current/tmp/restart.txt"
end
end
Any idea?
Thanks
Edit: Just checked and my disk space is full. Obviously this is my problem. An after update hook to prevent this?
From the comments:
check available disk space on the server for /tmp
df /tmp
free up space if necessary
alternatively configure capistrano to use a different folder to deploy to (How do I change the temporary directory that Capistrano uses?)
you may want to look at removing old releases if you are not already doing so
cap deploy:cleanup
Related
The documentation seems a little sparse on what this means.
I'm trying to set up an app deployed by a multistage capistrano script.
EDIT: I am trying to deploy the same app, twice to the same server. The only real difference (other than the git branches) is I want to deploy each copy to a different folder. The first instance is a staging where I can test the app in the exact same environment as the second instance, which is a production instance. Is capistrano able to do this?
I ran the staging deployment without any issues. However, when I run any tasks specifying my production stage, (such as deploy:setup, in this case) I receive the following error:
`deploy:setup' is only run for servers matching {:except=>{:no_release=>true}}, but no servers matched
Here's my Deploy.rb
require "rvm/capistrano"
require "bundler/capistrano"
require "capistrano/ext/multistage"
#server "direct.measuremyho.me", :web, :app, :db, primary: true
set :stages, %w{staging production} # Set staging and production environment
set :default_stage, "staging" # Use staging environment as the default one to prevent accidentally deploying to production
set :application, "mmh"
set :user, "mmh"
set :deploy_via, :remote_cache
#set :deploy_to, "/var/www/#{application}"
set :use_sudo, false
set :keep_releases, 3
set :scm, "git"
set :repository, "git#localhost:#{application}.git"
set :local_repository, "git#direct.measuremyho.me:#{application}.git"
#set :branch, "master"
default_run_options[:pty] = true
ssh_options[:forward_agent] = true
after "deploy:update_code", "deploy:migrate"
after "deploy", "deploy:cleanup"
namespace :deploy do
%w[start stop].each do |command|
desc "#{command} nginx server"
task command, roles: :app, except: {no_release: true} do
sudo "#{try_sudo} service nginx #{command}"
end
end
desc "restart passenger server"
task :restart, roles: :app, except: { no_release: true } do
run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}"
end
task :setup_config, roles: :app do
# link the nginx config file in the app
# sudo "ln -nfs #{current_path}/config/nginx.conf "\
# "/opt/nginx/conf/nginx.conf"
# make the shared rails config directory
run "mkdir -p #{shared_path}/config"
# ftp the database.yml file to that directory
put File.read("config/database.yml"), "#{shared_path}/config/database.yml"
# make the shared uploads directory
run "mkdir -p #{shared_path}/uploads"
# tell the user to edit database.yml
puts "==> IMPORTANT!!! Now edit database.yml in "\
"#{shared_path}/config <==="
end
after "deploy:setup", "deploy:setup_config"
task :symlink_config, roles: :app do
run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
run "rm -rf #{release_path}/public/uploads"
run "ln -nfs #{shared_path}/uploads #{release_path}/public/"
end
after "deploy:finalize_update", "deploy:symlink_config"
end
My staging.rb
set :application_directory, "staging"
set :rails_env, "staging"
set :main_server, 'direct.measuremyho.me'
set :branch do
default_tag = `git tag`.split("\n").last
tag = Capistrano::CLI.ui.ask "Tag to deploy (make sure to push the tag first): [#{default_tag}] "
tag = default_tag if tag.empty?
branch = "release/#{tag}"
branch
end
# Do not modify
# Set up the server
server "#{main_server}", :web, :app, :db, :primary => true
set :deploy_to, "/var/www/mmh/#{application_directory}"
My production.rb
set :application_directory, "production"
set :rails_env, "production"
set :main_server, 'direct.measuremyho.me'
set :branch, "master"
# Do not modify
# Set up the server
server "#{main_server}", :web, :app, :db, :primary => true
set :deploy_to, "/var/www/mmh/#{application_directory}"
My question is, why is this being set? Additionally, what can I do to avoid setting this variable so I can use the deploy commands.
Let me know if I've missed any pertinent information.
I have solved the problem for now by replacing the following line:
server "#{main_server}", :web, :app, :db, :primary => true
with:
server "#{main_server}", :web, :app, :db, :primary => true, :no_release => false
in my production.rb file.
However, this is a hacky solution, and I'd like to understand how I should properly deploy a rails app twice to the same server, for staging and production purposes. Or alternatively, why I should not do this, and what the alternatives are. So, I have left the question unanswered.
I am attempting to expand on this helpful answer by providing a tutorial that includes its steps, as well as setting up a self-hosted git repository instead of github and deployment scripts for staging and production versions of the app on the same server. So this question answers a pivotal piece of this process. I'm trying to get an idea of what the best practices are for a situation like this.
Comments welcomed; I'll add them to this answer.
I am deploying code with Capistrano, this is the content of deploy.rb:
require 'bundler/capistrano'
set :application, "project_name"
set :use_sudo, false
set :scm, :git
set :repository, "git#bitbucket.org:my_name/fileito.git"
set :branch, "master"
set :deploy_via, :remote_cache
#set :deploy_via, :copy
set :user, "deployer"
set :password, "password"
set :deploy_to, "/home/deployer/project_name"
#set :app_site, "ec2-xx-xxx-xx-xxx.compute-1.amazonaws.com"
set :app_site, "xx.xxx.xxx.xxx"
role :web, app_site # Your HTTP server, Apache/etc
role :app, app_site # This may be the same as your `Web` server
role :db, app_site, :primary => true # This is where Rails migrations will run
require 'capistrano-unicorn'
after 'deploy:restart', 'unicorn:reload' # app IS NOT preloaded
after 'deploy:restart', 'unicorn:restart' # app preloaded
set :whenever_command, "bundle exec whenever"
require "whenever/capistrano/recipes"
# Added:
after "deploy:stop", "deploy:start"
namespace :deploy do
task :start do
run "/etc/init.d/apache2 start"
end
task :stop do
run "/etc/init.d/apache2 stop"
end
task :restart, :roles => :app, :except => { :no_release => true } do
run "touch #{File.join(current_path,'tmp','restart.txt')}"
end
end
But when I deploy the new code and check the app in the browser, I see there still the old code. What's wrong? When I take a look into the current directory, there is the new code - I manually checked the files through the cat command.
How is possible that in browser is still the old version -> the old code?
Thanks
There are a variety of reasons that this can happen. Here are a few links you should check:
Unicorn continues to use old code following deploy + restart
Unicorn restarting in old release directory
Restarting Unicorn with USR2 doesn't seem to reload production.rb settings
I'm following this guide for deploying a rails app via capistrano: https://github.com/capistrano/capistrano/wiki/2.x-From-The-Beginning
I'm using linode as my VPS. I've done all the initial setup and cap deploy:setup/update/deploy all work. When I go to execute this command in my rails directory: $ rake RAILS_ENV=production db:schema:load. I get undefined method 'minutes' for 90:Fixnum. It seems that activesupport is somehow not installed, yet when I type rails --version, I get Rails 3.2.11. Any insight would be extremely helpful!
Here's my deploy.rb file:
require 'bundler/capistrano'
require "capistrano-rbenv"
set :rbenv_ruby_version, "1.9.3-p392"
set :application, "uganda-coords"
# Deploy from your local Git repo by cloning and uploading a tarball
set :scm, :git
set :repository, "git#github.com:benrudolph/myapp.git"
set :deploy_via, :copy
set :scm_passphrase, "mypassword"
set :branch, "master"
set :deploy_via, :remote_cache
set :rails_env, "production"
set :user, :root
set :deploy_to, "/var/www/#{application}"
set :use_sudo, false
set :ssh_options, { :forward_agent => true }
role :web, "176.58.105.165" # Your HTTP server, Apache/etc
role :app, "176.58.105.165" # This may be the same as your `Web` server
role :db, "176.58.105.165", :primary => true # This is where Rails migrations will run
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
Turns out this had to do with using 90.minutes in my application.rb file. I still don't know why this works on dev and not production.
When I run cap deploy at a certain point towards the end of the process, I get a password prompt...
** keeping 5 of 6 deployed releases
* executing "sudo -p 'sudo password: ' rm -rf /opt/deployed_rails_apps/myapp/releases/20120922200242"
servers: ["myhost.com"]
[username#myhost.com] executing command
Password:
Is there a way I can get it to complete without prompting me to enter a password?
Here's my deploy.rb...
require "bundler/capistrano"
require "rvm/capistrano"
set :rvm_ruby_string, 'ruby-1.9.3-p194#run_passenger'
set :rvm_type, :user
set :application, 'myapp'
set :repository, 'git#github.com:fakename/myrepository.git'
set :deploy_to, "/opt/deployed_rails_apps/#{application}"
set :scm, "git"
set :branch, "master"
set :deploy_via, :remote_cache
set :keep_releases, 5
after "deploy:update", "deploy:cleanup"
load 'deploy/assets'
role :app, 'username#myhost.com'
role :web, 'username#myhost.com'
namespace :deploy do
task :start, :roles => :app do
run "touch #{current_release}/tmp/restart.txt"
end
task :stop, :roles => :app do
# Do nothing.
end
desc "Restart Application"
task :restart, :roles => :app do
run "touch #{current_release}/tmp/restart.txt"
end
end
Assuming your deployment user has appropriate permissions and you don’t need to use sudo, you can set :use_sudo to false and Capistrano won’t use it.
Just add
set :use_sudo, false
to your deploy.rb.
Set up your SSH public key on the machine you're deploying to. This isn't a Capistrano thing. Here's one guide. There are many others that you can find with a quick search.
If you really need root permission in order to delete files under /opt/deployed_rails_apps/myapp/releases/ then you can edit the /etc/sudoers file to allow your deploy user to use sudo without the password.
But I suspect the answer by #matt using set :use_sudo, false should take care of your problem.
I've set this up before but can't get it to work now. I want a development and production site. When I do cap deploy it'll setup a "current" symlink (not sure how I did that since for a long time it wouldn't even do that). But how do I get it to deploy and setup the necessary symlink for dev/prod?
My deploy.rb file:
#require 'bundler/capistrano'
require 'capistrano/ext/multistage'
require 'capistrano_colors'
set :stages, %w(development production)
set :default_stage, 'development'
set :application, "myapp"
set :repository, "***"
# Target directory on the server
set :deploy_to, "/var/www/#{application}"
set :scm, :git
set :deploy_via, :remote_cache
set :user, '***'
set :use_sudo, false
role :web, "68.225.130.30" # Your HTTP server, Apache/etc
role :app, "68.225.130.30" # This may be the same as your `Web` server
role :db, "68.225.130.30", :primary => true # This is where Rails migrations will run
# List of symlinks to be generated. Keys are subdirectories of release_path.
SYMLINKS = { :config => ['database.yml'],
:public => ['system'] }
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')}"
# Not working =/
#run "touch /var/www/#{current_path}/tmp/restart.txt"
end
desc "Set up application symlinks."
task :app_symlinks do
SYMLINKS.keys.each do |key|
dir = key.to_s
SYMLINKS[key].each do |path|
run "ln -nfs #{shared_path}/#{dir}/#{path} #{release_path}/#{dir}/#{path}"
end
end
end
end
my deploy/development.rb file:
set :deploy_to, "/var/www/#{application}"
set :branch, "master"
unset :rails_env
set :rails_env, "development"
UPDATE/ANSWER:
Issue was with the current_path variable. Weird since I've tried using
set :current_path, "development"
and
set :current_path, "#{application}/development"
and it didn't work. Looks like I have to set the entire path, which seems weird since I've used the latter before.
set :current_path, "/var/www/#{application}/development"
Anyone know why?
:current_path is set by capistrano based on the :deploy_to path + the :application name. You can only use :current_path within your namespaced tasks.
In other words, it's a convenience variable used for creating symlinks, restarting servers, and other tasks.