Capistrano bower rails deployment issue - ruby-on-rails

I have installed bower in the app server and I am able to run bundle exec rake bower:install in any release or in current directory. But when I'm trying the same while cap production deploy, the following error is repeated.
Command:
cd /home/deploy/apps/xxxx/releases/20150910064532 && ~/.rvm/bin/rvm default do bundle exec rake bower:install CI=true
Bower not found! You can install Bower using Node and npm:
DEBUG [68147ae5] $ npm install bower -g
DEBUG [68147ae5] For more info see http://bower.io/
config in deploy.rb
namespace :bower do
desc 'Install bower'
task :install do
on roles(:web) do
within release_path do
execute :rake, 'bower:install CI=true'
end
end
end
end
before 'deploy:compile_assets', 'bower:install'

Related

How to run a bash script to update a Rails app from outside its directory?

I have this script that should be running from the /~ directory:
#!/bin/bash
APP=/root/apps/monitoring
cd $APP
git pull
rake assets:precompile RAILS_ENV=production
touch $APP/tmp/restart.txt
As you can see, it pulls new commits and updates the assets and restarts Apache. The problem is when it runs the line rake assets:precompile RAILS_ENV=production, It says:
Could not find proper version of rake (12.1.0) in any of the sources
Run `bundle install` to install missing gems.
Which is strange because I am supposed to be inside the app's folder (/root/apps/monitoring) when this command is executed. What I am doing wrong?
You may need to load rvm in the script (https://rvm.io/workflow/scripting) and may be select proper ruby/gemset.
Also you can consider using wrapper for bundle created with rvm wrapper
Please try
#!/bin/bash
APP=/root/apps/monitoring
cd $APP
git pull
bundle exec rake assets:precompile RAILS_ENV=production
touch $APP/tmp/restart.txt
With bundle exec it should work.
I run rake tasks using bash script wrappers. The trick is to use the source command to load in the rvm environment after the task is started
example.sh
#!/bin/bash
# change the directory
cd /home/ubuntu/GSeries
# load rvm ruby
source /home/ubuntu/.rvm/environments/ruby-2.4.2#mygemset
bundle exec rake db:prune_logs RAILS_ENV="production" &>> /home/ubuntu/GSeries/log/prune_logs.log

Deploy Rails 5.1 / Webpacker app with Capistrano

I have an Ubuntu server to deploy my Rails projects. In my Ubuntu server I had RVM.
Now I want to deploy new projects with Rails 5.1 and webpacker. To deploy this projects, I've installed NVM, npm and yarn in my Ubuntu server.
In my Rails 5.1 / Webpacker project I have following gems for capistrano deployment:
Gemfile
group :development do
gem 'capistrano-rails'
gem 'capistrano-rvm'
gem 'capistrano-passenger'
gem 'capistrano-nvm', require: false
gem 'capistrano-yarn'
end
In deploy.rb I've added some configurations for capistrano nvm and capistrano yarn.
deploy.rb
set :nvm_type, :user # or :system, depends on your nvm setup
set :nvm_node, 'v7.10.0'
set :nvm_map_bins, %w{node npm yarn}
set :yarn_target_path, -> { release_path.join('client') } #
set :yarn_flags, '--production --silent --no-progress' # default
set :yarn_roles, :all # default
set :yarn_env_variables, {}
Also I've added node_modules in linked_dirs.
deploy.rb
set :linked_dirs, %w{log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system node_modules client/node_modules}
The problem comes when I execute cap deploy in assets:precompile step. Next you have the error log.
terminal log
00:10 deploy:assets:precompile
01 /usr/local/rvm/bin/rvm 2.4.1#project do bundle exec rake assets:precompile
01 Yarn executable was not detected in the system.
01 Download Yarn at https://yarnpkg.com/en/docs/install
01 /home/deploy/rails/241/project/shared/bundle/ruby/2.4.0/bin/rake: No such file or directory - node
01 Node.js not installed. Please download and install Node.js https://nodejs.org/en/download/
(Backtrace restricted to imported tasks)
cap aborted!
SSHKit::Runner::ExecuteError: Exception while executing on host xxx.xxx.xxx.xxx: rake exit status: 1
rake stdout: Yarn executable was not detected in the system.
Download Yarn at https://yarnpkg.com/en/docs/install
/home/deploy/rails/241/project/shared/bundle/ruby/2.4.0/bin/rake: No such file or directory - node
Node.js not installed. Please download and install Node.js
https://nodejs.org/en/download/
rake stderr: Nothing written
SSHKit::Command::Failed: rake exit status: 1
rake stdout: Yarn executable was not detected in the system.
Download Yarn at https://yarnpkg.com/en/docs/install
/home/deploy/rails/241/project/shared/bundle/ruby/2.4.0/bin/rake: No such file or directory - node
Node.js not installed. Please download and install Node.js
https://nodejs.org/en/download/
rake stderr: Nothing written
Tasks: TOP => deploy:assets:precompile
(See full trace by running task with --trace)
The deploy has failed with an error: Exception while executing on host xxx.xxx.xxx.xxx: rake exit status: 1
rake stdout: Yarn executable was not detected in the system.
Download Yarn at https://yarnpkg.com/en/docs/install
/home/deploy/rails/241/project/shared/bundle/ruby/2.4.0/bin/rake: No such file or directory - node
Node.js not installed. Please download and install Node.js
https://nodejs.org/en/download/
rake stderr: Nothing written
** DEPLOY FAILED
** Refer to log/capistrano.log for details. Here are the last 20 lines:
DEBUG [016276ab] * spring (2.0.1)
DEBUG [016276ab] * spring-watcher-listen (2.0.1)
DEBUG [016276ab] * web-console (3.5.0)
DEBUG [016276ab] Install missing gems with `bundle install`
DEBUG [016276ab] Finished in 0.677 seconds with exit status 1 (failed).
INFO [86e74b01] Running /usr/local/rvm/bin/rvm 2.4.1#project do bundle install --path /home/deploy/rails/241/project/shared/bundle --without development test --deployment --quiet on xxx.xxx.xxx.xxx
DEBUG [86e74b01] Command: cd /home/deploy/rails/241/project/releases/20170511083021 && ( export NODE_VERSION="v7.10.0" ; /usr/local/rvm/bin/rvm 2.4.1#project do bundle install --path /home/deploy/rails/241/project/shared/bundle --without development test --deployment --quiet )
DEBUG [86e74b01] Warning, new version of rvm available '1.29.1', you are using older version '1.26.11'.
You can disable this warning with: echo rvm_autoupdate_flag=0 >> ~/.rvmrc
You can enable auto-update with: echo rvm_autoupdate_flag=2 >> ~/.rvmrc
INFO [86e74b01] Finished in 3.209 seconds with exit status 0 (successful).
DEBUG [4a428031] Running if test ! -d /home/deploy/rails/241/project/releases/20170511083021; then echo "Directory does not exist '/home/deploy/rails/241/project/releases/20170511083021'" 1>&2; false; fi on xxx.xxx.xxx.xxx
DEBUG [4a428031] Command: if test ! -d /home/deploy/rails/241/project/releases/20170511083021; then echo "Directory does not exist '/home/deploy/rails/241/project/releases/20170511083021'" 1>&2; false; fi
DEBUG [4a428031] Finished in 0.066 seconds with exit status 0 (successful).
INFO [d225a8b5] Running /usr/local/rvm/bin/rvm 2.4.1#project do bundle exec rake assets:precompile on xxx.xxx.xxx.xxx
DEBUG [d225a8b5] Command: cd /home/deploy/rails/241/project/releases/20170511083021 && ( export NODE_VERSION="v7.10.0" RAILS_ENV="production" ; /usr/local/rvm/bin/rvm 2.4.1#project do bundle exec rake assets:precompile )
DEBUG [d225a8b5] Yarn executable was not detected in the system.
Download Yarn at https://yarnpkg.com/en/docs/install
DEBUG [d225a8b5] /home/deploy/rails/241/project/shared/bundle/ruby/2.4.0/bin/rake: No such file or directory - node
DEBUG [d225a8b5] Node.js not installed. Please download and install Node.js https://nodejs.org/en/download/
Thanks in advance!
I prefer to compile assets locally and then copy to the production servers with rsync:
# lib/capistrano/tasks/precompile.rake
namespace :assets do
desc 'Precompile assets locally and then rsync to web servers'
task :precompile do
run_locally do
with rails_env: stage_of_env do
execute :bundle, 'exec rake assets:precompile'
end
end
on roles(:web), in: :parallel do |server|
run_locally do
execute :rsync,
"-a --delete ./public/packs/ #{fetch(:user)}##{server.hostname}:#{shared_path}/public/packs/"
execute :rsync,
"-a --delete ./public/assets/ #{fetch(:user)}##{server.hostname}:#{shared_path}/public/assets/"
end
end
run_locally do
execute :rm, '-rf public/assets'
execute :rm, '-rf public/packs'
end
end
end
# config/deploy.rb
after 'deploy:updated', 'assets:precompile'
In your Capfile you need to include all the capistrano tasks:
# Load custom tasks from `lib/capistrano/tasks` if you have any defined
Dir.glob('lib/capistrano/tasks/**/*.rake').each { |r| import r }
This eliminates the need to install node and yarn on the production servers.
Of course you need node and yarn installed locally
What worked for me was making sure NVM was included in the PATH. By default, in a bash terminal, NVM adds its environment variables to the end of ~/.bashrc, but much of that file is not usually executed in a non-interactive terminal (which Capistrano runs in). I found this comment helpful:
Put your NVM source script in your .bashrc which is still evaluated even during an non-interactive SSH session. Just make sure you place the declarations at the top, before the case statement:
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
The error tells you pretty much what's wrong. Neither Yarn or Node can be found on the server. Your installation might be incorrect.
Follow instructions to install both here:
https://nodejs.org/en/download/package-manager/#debian-and-ubuntu-based-linux-distributions
and here:
https://yarnpkg.com/lang/en/docs/install/#linux-tab
Then make sure you can call:
yarn
node
On the server. If not, you might need to add paths to executables into your PATH variable
First - Install Yarn
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt update && sudo apt install yarn
Second - Install NodeJS(now 14 is newest):
curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -
sudo apt-get install -y nodejs

Protractor tests failing on Codeship due to 405 API response

The protractor configuration and scripts work as expected both on our local development environment and in a continuous integration environment (similar to Codeship).
The project structure is the following (I'm describing the Codeship env. status below):
The AngularJS app requests data from the REST API build with the Ruby on rails app, using AJAX requests.
In our Codeship configuration we set up the rails app, migrate and seed the database so that all necessary data is available.
The AngularJS app is also configured correctly since the login page is rendered as expected (I'm doing a print screen, and the main page is loaded correctly).
The usename and password are filled in by protractor using valid credentials (available in the mysql DB).
But when clicking the 'Log In' button the returned response from the AJAX call is a 405 Method Not Allowed.
As we never encountered this response in our other environments we believe it has something to do with the specific codeship setup.
Any thoughts why the API would return 405 only on Codeship?
The setup is below:
rvm use 2.2.0 --install
cp config/database.codeship.yml config/database.yml
bundle install
export RAILS_ENV="test"
bundle exec rake db:drop RAILS_ENV=test
bundle exec rake db:create RAILS_ENV=test
bundle exec rake db:test:prepare
bundle exec rake db:migrate RAILS_ENV=test
bundle exec rake seed:migrate RAILS_ENV=test
cd frontend && npm install && cd ..
npm install -g grunt-cli
npm install -g http-server
cd frontend && npm install bower && cd ..
cd frontend && bower install && cd ..
cd frontend && grunt build && cd ..
cd frontend && webdriver-manager update --standalone && cd ..
export RAILS_ENV="development"
rake db:structure:load
rake seed:migrate
http-server public -a 127.0.0.1 -p 9000 > /dev/null &
http-server app > /dev/null &
bundle exec rake
cd frontend && grunt test && cd ..
Here is the part of the screenshot that shows the API response:
In the end, the solution for us was to use protractor-rails
- basically using the base url of the rails server instead of trying to run the app on a different URL through grunt. Our setup now looks like this:
rvm use 2.2.0 --install
cp config/database.codeship.yml config/database.yml
bundle install
# protractor tests
export RAILS_ENV="development"
rake db:structure:load
rake seed:migrate
npm install
webdriver-manager update
bundle exec rake protractor:init RAILS_ENV=development
bundle exec rake protractor:spec RAILS_ENV=development
# rails tests
bundle exec rake db:test:prepare
bundle exec rake db:migrate RAILS_ENV=test
bundle exec rake seed:migrate RAILS_ENV=test
bundle exec rake

Capistrano deploy:migrate Could not find rake-0.9.2.2 in any of the sources

My Capistrano deploy:migrate task is set to run a simple rake db:migrate command, as follows:
env PATH=/home/user/.gems/bin sh -c 'cd /home/user/app/releases/20121003140503 && rake RAILS_ENV=production db:migrate'
When I run this task during an ssh session manually it completes successfully. However when I run from my local development box, I receive the following error:
** [out :: app] Could not find rake-0.9.2.2 in any of the sources
I am able to locate my rake gem by typing which rake via ssh (/home/user/.gems/bin/rake) and rake --version gives me "rake, version 0.9.2.2," so I don't understand why this command fails via Capistrano?
Capistrano does not place bundle exec before rake command in default. If you are sure you have the rake gem in your bundle, try adding this to your deploy.rb.
set :rake, 'bundle exec rake'
This will tell Capistrano to instead of just rake run bundle exec rake. If it is in your bundle, you won't have any problems any more and you will also avoid collisions if you have more versions of rake installed on your system.
You might also just need to bundle your gems with this:
require "bundler/capistrano"
Via: Why is Capistrano not installing gems with bundler?
Once you go into your app folder, you simply type:
$bundle exec rake instead of just $rake

Prevent whenenver gem from running --clear-crontab before gems installed

I am using capistrano, and the whenever gem, on a fresh deploy to a server without the whenever gem installed, capistrano attempts to run
whenever --clear-crontab
BEFORE the rake gems:install command has been run, its clear (from this) that this command runs after deploy_code but so does my command that installs the gems (below)..
after "deploy:update_code", "deploy:symlink_config"
deploy.task :symlink_config, :roles => :app do
# create a symlink to the database.yml file located in the shared_path
run "ln -nsf #{shared_path}/config/database.yml #{current_release}/config"
# install any missing gems
run "cd #{current_release} && sudo rake gems:install --trace RAILS_ENV=#{rails_env}"
# migrate the database
run "cd #{current_release} && rake db:migrate --trace RAILS_ENV=#{rails_env}"
end
Is there a way to order these tasks, because on a cold deploy I always get whenever: not found and have to manually install the whenever gem on the remote server
What I ended up doing is removing the require "whenever/capistrano" from the config\deploy.rb to avoid the "automatic" deploy. Instead I have added a task that executes the --clear-crontab and --update-crontab. This works as it will execute in the sequence I set it to.
I have based it off this post, which deals with a slightly different problem but has the same solution - not to use the "automatic" integration with capistrano.

Resources