The Capistrano production.rb file executes 3 tasks
composer install --no-dev
mkdir storage
upload! ".env.production", ".env"
The first 2 are executed, but the upload fails: "No such file or directory".
I was able to scp the file successfully from the command line.
How to copy a file to the current release directory?
$ cap --version
Capistrano Version: 3.11.0 (Rake Version: 12.3.1)
$ cap production deploy
...
01 mkdir -p ~/public_html/app/releases/20181122210112
...
composer install --no-dev
...
mkdir storage
...
SSHKit::Runner::ExecuteError:
Exception while executing as me#site.com:
scp: ~/public_html/app/releases/20181122210112/.env:
No such file or directory
DEBUG Uploading .env.production 0.0%
...
$
scp the file successfully from the command line:
$ scp .env.production me#site.com:~/public_html/app/releases/20181122210112/.env
production.rb
# use absolute path
set :deploy_to, "/home/user/public_html/app"
namespace :deploy do
desc "Install app dependencies with composer"
after :updated, :build do
on roles(:web) do
within release_path do
execute :composer, "install --no-dev"
execute :mkdir, "storage"
end
end
end
end
namespace :deploy do
desc "Copy Env"
after :finished, :copy do
on roles(:all) do
upload! ".env.production", "#{release_path}/.env"
end
end
end
if your need is to copy your local application.yml to the server, and you are already using capistrano, you can use the capistrano figaro gem, it creates a task to update this file on server. in theory, you could run the task automatically and make this file to be updated. is an old gem, but works like a charm and do the work.
Related
I am attempting to write a Capistrano task that will 'deploy' a private gem I wrote to accompany a Rails project.
In config/deploy.rb
after :updating, :retrieve_my_gem
The file lib/capistrano/tasks/retrieve_my_gem.rake contains...
desc 'Clones my_gem from Github to vendor/git'
task :retrieve_my_gem do
on roles(:app), in: :sequence do
# Create the directory that will contain my gem
gem_container_path = release_path.join('vendor/git')
debug "Gem container path: #{gem_container_path}"
if test "[ ! -d #{gem_container_path} ]"
info "Creating local gem directory"
execute 'mkdir', '-p', gem_container_path
end
gem_path = release_path.join('vendor/git/my_gem')
debug "Gem path: #{gem_path}"
if test "[ ! -d #{gem_path} ]"
within gem_container_path do
info "Cloning my gem to #{gem_path}"
execute 'git clone git#github.com:username/my_gem.git', gem_path
end
else
within gem_path do
info "Updating my gem in #{gem_path}"
execute 'git pull'
end
end
end
end
And Gemfile has...
gem 'my_gem', :path => 'vendor/git/my_gem/'
When I run my deploy task, the gem_container_path is created but it clones the repo my_gem into ~/my_gem instead of into gem_container_path. The deploy task continues and fails when attempt bundle install due to not finding 'my_gem' in 'vendor/git/my_gem/' as indicated in the Gemfile.
I am expecting the task to clone the repo to /var/www/project/releases/*/vendor/git/my_gem where * is replaced with the DateTime stamp that Capistrano generates for this release.
Why is Capistrano cloning the repo to my remote user's home directory and not to the specified path?
The issue was my execute statement:
execute 'git clone git#github.com:username/my_gem.git', gem_path
I changed it to
execute "git clone git#github.com:username/my_gem.git #{gem_path}"
and it is working as expected now.
Having a really hard time getting this to work. I just added dotenv gem to accommodate for the Rails 4.1 secrets.yml file. I also have in the .env file the database.yml's password.
To add to my deploy:
set :linked_files, %w{config/database.yml .env}
When I run cap production deploy I get:
/shared/config/database.yml does not exist on 107.170.....
How can I get the database.yml to be added?
I looked at the capistrano touch gem with no luck because after I create the empty files, ActiveRecord throws an error of No 'production' database
Create task for upload your .env and database.yml.Look example below:
desc "Database config"
task :setup_config, roles: :app do
# upload you database.yml from config dir to shared dir on server
put File.read("config/database.yml"), "#{shared_path}/config/database.yml"
# make symlink
run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
# upload you database.yml from config dir to shared dir on server
put File.read(".env"), "#{shared_path}/config/.env"
# make symlink
run "ln -nfs #{shared_path}/config/.env #{current_path}/.env"
end
And add before and after hooks.
Or use dotenv-deployment that contain the same tasks.
I'm getting an "upload via scp failed" error when I run cap deploy, with the following output:
* executing `deploy:assets:update_asset_mtimes'
...
** Updating mtimes for ~8 assets...
** scp upload #<StringIO:0x007fca13a94f40> -> /apps/my_app/TOUCH_ASSETS
*** upload via scp failed on <ip>:
*** (
*** )
*** [deploy:update_code] rolling back
When I ran cap deploy:cold, there were no errors.
What is the source of this error and how do I go about debugging it?
In your Capistrano deployments file, you are passing a StringIO to the scp command instead of a file name. If the StringIO object in question contains the name of the file(s) you wish to copy, then you must convert the StringIO to a string:
stringIOobject.read()
It may be that your asset manifest file isn't correctly formatted, such as having a typo. Look in the following manifest files in your project and double check everything.
app/assets/javascripts/application.js
app/assets/stylesheets/application.css
If you have any other custom manifest files be sure to check them out too. Look at the examples here to make sure the formatting is correct.
Try compile your assets locally and then upload via rsync, like this
namespace :deploy do
namespace :assets do
desc "Precompile assets on local machine and upload them to the server."
task :precompile, roles: :web, except: {no_release: true} do
run_locally "bundle exec rake assets:precompile"
find_servers_for_task(current_task).each do |server|
run_locally "rsync -vr --exclude='.DS_Store' public/assets #{user}##{server.host}:#{shared_path}/"
end
end
end
end
I'm having problems deploying the Whenever gem to my production environment using Capistrano.
The problem is stemming from a bundle exec whenever command that's triggering some 'missing gem' issues (yet running bundle install from the shell shows that everything is in fact there!).
My feeling is that one of two things is happening: that Bundler isn't fully loading before bundle exec is being called, or that somehow there's a path issue that's running it in the wrong place.
Here's what's going on:
* executing `deploy'
* executing `deploy:update'
** transaction: start
* executing `deploy:update_code'
executing locally: "git ls-remote git#my-source-repository:mysource.git HEAD"
command finished in 1847ms
* executing "git clone -q git#my-source-repository:mysource.git /domains/myapp/releases/20130124211036 && cd /domains/myapp/releases/20130124211036 && git checkout -q -b deploy 90238bbcb993e3e7df2374ffaa13e7ed701c202e && (echo 90238bbcb993e3e7df2374ffaa13e7ed701c202e > /domains/myapp/releases/20130124211036/REVISION)"
servers: ["myip"]
[myip] executing command
** [myip :: out] Enter passphrase for key '/home/deploy/.ssh/id_rsa':
** [myip :: out]
command finished in 9294ms
* executing `deploy:finalize_update'
triggering before callbacks for `deploy:finalize_update'
* executing `whenever:update_crontab'
* executing "cd /domains/myapp/releases/20130124211036 && bundle exec whenever --update-crontab My App --set environment=production --roles db"
servers: ["myip"]
[myip] executing command
** [out :: myip] Could not find carrierwave-0.5.8 in any of the sources
** [out :: myip] Run `bundle install` to install missing gems.
command finished in 1967ms
*** [deploy:update_code] rolling back
* executing "rm -rf /domains/myapp/releases/20130124211036; true"
servers: ["myip"]
[myip] executing command
command finished in 998ms
failed: "rvm_path=/usr/local/rvm /usr/local/rvm/bin/rvm-shell '1.9.3' -c 'cd /domains/myapp/releases/20130124211036 && bundle exec whenever --update-crontab My App --set environment=production --roles db'" on myip
You can see that the failure is coming from this line:
bundle exec whenever --update-crontab
Which is in turn being run by my Capistrano deploy.rb.
# Your Application's "Name"
set :application, [My App]
# The URL to your application's repository
set :repository, [repo]
set :scm, :git
set :scm_passphrase, [password]
# The user you are using to deploy with (This user should have SSH access to your server)
set :user, "deploy"
# We want to deploy everything under your user, and we don't want to use sudo
set :use_sudo, false
# Where to deploy your application to.
set :deploy_to, "/domains/myapp/"
# Load RVM's capistrano plugin.
require "rvm/capistrano"
set :rvm_ruby_string, '1.9.3'
set :rvm_type, :system # use system-wide RVM
# Require that we use bundler to install necessary gem dependencies
require "bundler/capistrano"
set :whenever_command, "bundle exec whenever"
require "whenever/capistrano"
# -------------------------------- Server Definitions --------------------------------
# Define the hostname of your server. If you have multiple servers for multiple purposes, we can define those below as well.
set :server_name, [server]
# We're assuming you're using a single server for your site, but if you have a seperate asset server or database server, you can specify that here.
role :app, server_name
role :web, server_name
role :db, server_name, :primary => true
# -------------------------------- Final Config --------------------------------
# This configuration option is helpful when using svn+ssh but doesn't hurt anything to leave it enabled always.
default_run_options[:pty] = true
namespace :deploy do
desc "Tell Passenger to restart the app."
task :restart do
run "touch #{deploy_to}current/tmp/restart.txt"
end
task :start do
run "cd #{deploy_to} && ln -s current/public public_html"
run "touch #{deploy_to}current/tmp/restart.txt"
end
task :symlink do
run "cd #{deploy_to} && rm current ; ln -s releases/#{release_name} current"
end
task :stop do
run "rm #{deploy_to}public_html"
end
namespace :web do
task :disable do
run "cd #{deploy_to} && rm public_html && ln -s static_site public_html"
end
task :enable do
run "cd #{deploy_to} && rm public_html && ln -s current/public public_html"
end
end
desc "Symlink shared configs and folders on each release."
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"
# create symlink to uploads folder for Carrierwave resources (i.e., book cover images)
run "ln -nfs #{shared_path}/uploads #{release_path}/public/uploads"
end
desc "Sync the public/assets directory."
task :assets do
system "rsync -vr --exclude='.DS_Store' public/assets #{user}##{application}:#{shared_path}/"
end
end
after "deploy", "deploy:migrate"
after 'deploy:update_code', 'deploy:symlink_shared'
after(:setup) do
run "rm -rf #{deploy_to}public_html"
run "mkdir #{deploy_to}static_site"
end
Now, the error that I'm getting about CarrierWave is bogus - I've been using CarrierWave for ages - and the issue clearly stems (as you can see by the command that triggers the error) from either Whenever itself or Bundler.
And I'm thinking that it actually may have something to do with paths related to RVM. At any rate, the bundle exec whenever isn't working.
Any ideas?
It turns out there were a couple problems, both of which needed addressing:
Whenever ~> 0.8 introduced a bug with Capistrano roles
The Whenever cap task was firing before bundle:install (this is confirmed in your code above)
See issues here: https://github.com/javan/whenever/issues/275 and here: https://github.com/javan/whenever/issues/269
To fix the problem, you most likely need to
Update bundler on your server (-v 1.2.3)
Update bundler locally
Update to the newest Whenever (-v 0.8.2)
#ideaoforder's answer helped me too, previously though I had the same trouble caused by require 'whenever/capistrano' being on the top of the config/deploy.rb followed by require 'bundler/capistrano'. Swapping those two helped.
I have require 'bundler/capistrano' always on top of the deploy script as a rule.
I am trying to deploy my rails application for the first time.
Server is running Ubuntu 10.4 server (64bit)
Local machine is running Windows XP.
Repository is at github
I have successfully run
cap deploy:setup
but when I run
cap deploy:cold
I get the following error:
D:\Rails\rails_apps\fx>cap deploy:cold
You are running Ruby 1.8.6, which has a bug in its threading implementation.
You are liable to encounter deadlocks running Capistrano, unless you install
the fastthread library, which is available as a gem:
gem install fastthread
* executing `deploy:cold'
* executing `deploy:update'
** transaction: start
* executing `deploy:update_code'
updating the cached checkout on all servers
*** [deploy:update_code] rolling back
* executing "rm -rf /var/www/fx/releases/20100818215651; true"
servers: ["pragmaticriskmanagement.gotdns.com"]
[pragmaticriskmanagement.gotdns.com] executing command
command finished
D:/Rails/ruby/lib/ruby/gems/1.8/gems/capistrano-2.1.0/lib/capistrano/recipes/deploy.rb:37:in ``': No such file or directory - git rev-parse master (Errno::ENOENT)
from D:/Rails/ruby/lib/ruby/gems/1.8/gems/capistrano-2.1.0/lib/capistrano/recipes/deploy.rb:37:in `load'
from D:/Rails/ruby/lib/ruby/gems/1.8/gems/capistrano-2.1.0/lib/capistrano/recipes/deploy.rb:87:in `with_env'
from D:/Rails/ruby/lib/ruby/gems/1.8/gems/capistrano-2.1.0/lib/capistrano/recipes/deploy.rb:37:in `load'
from D:/Rails/ruby/lib/ruby/gems/1.8/gems/capistrano-2.1.0/lib/capistran/recipes/deploy/scm/git.rb:154:in `query_revision'
from D:/Rails/ruby/lib/ruby/gems/1.8/gems/capistrano-2.1.0/lib/capistrano/recipes/deploy/scm/base.rb:35:in `send'
from D:/Rails/ruby/lib/ruby/gems/1.8/gems/capistrano-2.1.0/lib/capistrano/recipes/deploy/scm/base.rb:35:in `method_missing'
from D:/Rails/ruby/lib/ruby/gems/1.8/gems/capistrano-2.1.0/lib/capistrano/recipes/deploy/scm/base.rb:63:in `local'
from D:/Rails/ruby/lib/ruby/gems/1.8/gems/capistrano-2.1.0/lib/capistrano/recipes/deploy/scm/base.rb:35:in `method_missing'
... 39 levels...
from D:/Rails/ruby/lib/ruby/gems/1.8/gems/capistrano-2.1.0/lib/capistrano/cli/execute.rb:14:in `execute'
from D:/Rails/ruby/lib/ruby/gems/1.8/gems/capistrano-2.1.0/bin/cap:4
from D:/Rails/ruby/bin/cap:19:in `load'
from D:/Rails/ruby/bin/cap:19
Here is my 'deploy.rb' file
set :application, "fx" #"pragmaticriskmanagement.gotdns.com"
set :repository, "git#github.com:jmedding/Fx.git"
set :deploy_to, "/var/www/#{application}"
set :git_enable_submodules, 1 # Make sure git submodules are populated
set :location, "pragmaticriskmanagement.gotdns.com"
set :user, "xxxxx"
set :use_sudo, false
set :scm, :git
role :app, location #"your app-server here"
role :web, location #"your web-server here"
role :db, location, :primary => true #"your db-server here", :primary => true
namespace :deploy do
desc "Restart Application"
task :restart, :roles => :app do
run "touch #{current_path}/tmp/restart.txt"
end
desc "Make symlink for database.yml"
task :symlink_dbyaml do
run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
end
desc "Create empty database.yml in shared path"
task :create_dbyaml do
run "mkdir -p #{shared_path}/config"
put '', "#{shared_path}/config/database.yml"
end
end
after 'deploy:setup', 'deploy:create_dbyaml'
after 'deploy:update_code', 'deploy:symlink_dbyaml'
after "deploy", "deploy:cleanup"
and now I'm stuck...
Any help would be greatly appreciated.
Thanks,
Jon
Sorry to resurrect such an old thread, but I solved this by adding the default location of my git binaries (C:\Program Files (x86)\Git\bin) to my PATH variable.
Ok, I have made some progress.
It seems that the error indicates that the git ls-remote command could not be found on the local system (win xp). As a test, I opened the GIT Bash shell and tried the command - it worked. Next, I tried
cap deploy
from the GIT Bash shell. Command not found. OK, I added my rails path
D:\Rails\ruby\bin
to the windows 'path' variable. Now, try
cap deploy
from the bash shell. This seems to have solved this problem, which now leads to my next problem
** [xxxxxxxx.com :: out] Cloning into /var/www/fx/shared/cached-copy...
** [xxxxxxxx.com :: err] Permission denied (publickey).
** [xxxxxxxx.com :: err] fatal: The remote end hung up unexpectedly
I can successfully run cap deploy from my linux box with the same public key. Also, I can push to my Github repo from this laptop with this key. Of course, the key in question should be on the server, but if it works when I run 'cap' from the linux box, why wouldn't it run from here?