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.
Related
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.
When trying to deploy a Rails app to a production server with Capistrano, it doesn't seem to recognize my project as being a git repo, despite me having cloned the project directly from GitHub.
THE GIT LOG:
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
CAP LOG:
$ cap production deploy
triggering load callbacks
* 2016-06-01 16:30:26 executing `production'
triggering start callbacks for `deploy'
* 2016-06-01 16:30:26 executing `multistage:ensure'
* 2016-06-01 16:30:26 executing `deploy'
* 2016-06-01 16:30:26 executing `deploy:update'
** transaction: start
* 2016-06-01 16:30:26 executing `deploy:update_code'
executing locally: "git ls-remote git#github.com:mitigation/mpm.git r1"
command finished in 662ms
* refreshing local cache to revision 8c86d067abde1464f88902566324a99e22cd3147 at /var/folders/xs/5qz1glwj30v51rwpxhyclw880000gn/T/mpm
executing locally: cd /var/folders/xs/5qz1glwj30v51rwpxhyclw880000gn/T/mpm && git fetch -q origin && git fetch --tags -q origin && git reset -q --hard 8c86d067abde1464f88902566324a99e22cd3147 && git clean -q -d -x -f
fatal: Not a git repository (or any of the parent directories): .git
command finished in 13ms
shell command failed with return code pid 52560 exit 128
Here's my Capfile:
load 'deploy'
load 'deploy/assets'
load 'config/deploy'
Here's my DEPLOY.RB:
require 'soprano'
require 'bundler/capistrano'
require 'capistrano/ext/multistage'
require 'whenever/capistrano'
require 'leipreachan/capistrano2'
set :default_environment, {
'PATH' => '/home/deploy/.rbenv/shims:/home/deploy/.rbenv/bin:$PATH'
}
set :web_server, :nginx
set :keep_releases, 3
set :repository, 'git#github.com:mitigation/mpm.git'
set :deploy_via, :copy
set :copy_exclude, %w(.git .idea .yardoc tmp log .DS_Store doc/* public/uploads.tar db/*.sql vendor/cache)
set :copy_cache, true
set :bundle_without, [:development, :test]
set :bundle_flags, '--deployment --binstubs'
set :user, 'deploy'
before 'deploy:setup', :db
after 'deploy:create_symlink', 'utils:version'
after 'deploy:update_code', 'db:symlink'
#For troubleshooting only
namespace :deploy do
task :update_code, :except => { :no_release => true } do
#on_rollback { run "rm -rf #{release_path}; true" }
strategy.deploy!
finalize_update
end
end
During deploys to various environments, capistrano3 creates a directory tree and puts the git information in a folder called repo_path. You'd have to travel inside that directory on your production server and "$git log" would work indicated its a .git repo
You also shouldn't need .git in your copy_exclude.
Try running through the capistrano3 set up process all over again with your app for different environments.
I would like to create Rails application template, so when I run rails new it should:
override Gemfile (add gems, remove gems and those shitty comments etc.)
convert application layout file to HAML and edit its content
edit assets files to import bootstrap-sass files as required
edit and set my database variables in database.yml
maybe something else, dunno atm...
I just want it to be ready to go, I hope you can understand me so far.
How could I achieve this?
I know about rails composer, but I don't want to choose from these application templates, I want the one with constant set of tools I always use. I can commit new application to GitHub and then just run git clone on it each time with just changing my new project name, but is it the best solution?
You can use the awesome Rails feature Rails Application Templates, rails new project_name -m /path/to/template.rb
Here is my own template:
# minitest, capistrano, pry
gem_group :development do
gem 'puma'
gem 'capistrano', '2.15.5'
gem 'rvm-capistrano'
gem 'pry-rails', '~> 0.3.2'
end
gem_group :test do
gem 'minitest-rails'
gem 'letter_opener'
gem 'ffaker', require: false
end
run "bundle install"
#install minitest test_helper
generate 'mini_test:install'
environment "config.generators do |g|\n g.test_framework :mini_test, spec: true, fixture: true\n end"
#Add pride to minitest config
run "sed -i '' '4 s#^#require \"minitest/pride\"#' test/test_helper.rb"
#create postgres DB in postgresql
#development and test
run "psql -c 'CREATE DATABASE #{app_path}_development;'"
run "psql -c 'CREATE DATABASE #{app_path}_test;'"
#add database yml
run "sed -i '' '4 s#^#require \"minitest/pride\"#' test/test_helper.rb"
#Add minitest features to Rake task
run %q^echo 'MiniTest::Rails::Testing.default_tasks << "features"' >> Rakefile^
#Fix README.md
run "rm README.rdoc"
run "touch README.md"
#Initialize local Git repository and Initial Commit
git :init
git add: "."
git commit: "-a -m 'Initial commit :pray:'"
I am trying to deploy rails app through chef . code deployed successfully ,but bundle install throwing error for specific gems , When installed manually gem installs without any issues , as per the chef error i got to know that , to execute bundle install chef uses its embedded ruby version and path for the same , but system is installed with ruby 2.0 using rvm .Can we override the chef ruby path to system ruby path ? I am using following code to deploy ,
deploy_branch "master" do
repo repo_url
migrate false
action :deploy
branch 'master'
enable_submodules true
before_migrate do
current_release_directory = release_path
running_deploy_user = new_resource.user
bundler_depot = new_resource.shared_path + '/bundle'
excluded_groups = %w(development test)
script 'Bundling the gems' do
interpreter 'bash'
cwd current_release_directory
user running_deploy_user
code <<-EOS
bundle install --quiet --deployment --path #{bundler_depot} \
--without #{excluded_groups.join(' ')}
EOS
end
end
end
I have been using capistrano for a while and I also use sitemap_generator. But now I wanted to put the sitemap_generator into the deployment process. According to: Github sitemap generator I only need to require it in the capfile.
But once I run capistrano it cannot load the file.
Thx for help
The capistrano tasks included with the sitemap_generator gem are for capistrano 3.0.
Assuming you're probably on 2.x, you can create a task that calls the rake sitemap refresh task for you through bundler.
# recipes/sitemap.rb
namespace :sitemap do
desc "Generate sitemap.xml.gz"
task :generate, roles: :web do
run "cd #{deploy_to}/current && /usr/bin/env bundle exec rake sitemap:refresh RAILS_ENV=#{rails_env}"
end
after "deploy:restart", "sitemap:generate"
end
This example regenerates the sitemap after the deploy:restart task, but the task can be called directly.