I am using Capistrano gem for deploy management of my Ruby on Rails app. Its connected with AWS server, EC2, MySQL Redis. While I am putting my command "cap production deploy" or "cap staging deploy" nothing happens. I just got stuck there.
To add here my SSH key is properly added. And in my AWS security groups, only the authorized IPs are added to have the permission of deploying. My IPs are also added.
But when I add open ports 0.0.0.0/0 in all security groups it allows me to deploy. But I shouldn't add open ports for the sace of application security.
What can be the reason and how to solve these?
screenshot of my console, nothing happens
Below is my deploy.rb file:
SSHKit.config.command_map[:rake] = 'bundle exec rake'
# config valid only for current version of Capistrano
lock '3.8.1'
set :application, 'my_app'
set :repo_url, 'git#gitlab.com:_____'
set :deploy_via, :remote_cache
set :rvm_roles, [:app, :web]
set :rvm_type, :user
set :rvm_ruby_version, 'ruby-2.4.0'
set :log_level, :debug
set :pty, false
set :linked_files, %w{config/application.yml config/database.yml}
set :linked_dirs, %w{log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system public/assets public/uploads}
set :keep_releases, 10
set :whenever_roles, [:web, :app,:db]
set :whenever_identifier, "#{fetch(:application)}_#{fetch(:stage)}"
namespace :deploy do
desc 'restart (upgrade) unicorn server'
task :restart do
invoke 'unicorn:restart'
end
after :finishing, 'deploy:cleanup'
after 'deploy:publishing', 'deploy:restart'
after :restart, :clear_cache do
on roles(:web), in: :groups, limit: 3, wait: 10 do
within release_path do
execute :rake, 'tmp:cache:clear'
end
end
end
end
namespace :delayed_job do
desc 'List of running delayed job workers'
task :list do
on roles(:all) do |host|
execute :ps, 'aux | grep delayed_job'
end
end
desc 'Stop delayed_job workers forcefully'
task :kill do
on roles(:all) do |host|
execute :kill, "-9 $(ps aux | grep delayed_job | awk '{print $2}')"
end
end
end
task :upload_secret_files do
on roles(:all) do |host|
begin
execute "mkdir -p #{shared_path}/config"
rescue
end
upload! 'config/application.yml', "#{shared_path}/config/application.yml"
upload! 'config/database.yml', "#{shared_path}/config/database.yml"
end
end
task :log do
on roles(:all) do |host|
execute "tail -f #{current_path}/log/#{fetch(:rails_env)}.log"
end
end
desc 'Invoke a rake command on the remote server'
task :invoke, [:command] => 'deploy:set_rails_env' do |task, args|
on primary(:app) do
within current_path do
with rails_env: fetch(:rails_env) do
rake args[:command]
end
end
end
end
I was struggling with exactly the same issue and spent several hours. Didn't get what is the issue related to. It just started working after I reboot my local OS
Related
after i try to deploy my app via capistrano to my server i get this error message:
DEBUG [605f198a] Finished in 0.084 seconds with exit status 1 (failed).
ERROR linked file /home/deploy/myrailsapp/shared/config/database.yml does not exist on xx.xxx.xx.xxx
(Backtrace restricted to imported tasks)
cap aborted!
SSHKit::Runner::ExecuteError: Exception while executing as deploy#xx.xxx.xx.xxx: exit
SystemExit: exit
Tasks: TOP => deploy:check:linked_files
(See full trace by running task with --trace)
The deploy has failed with an error: Exception while executing as deploy#xx.xxx.xx.xxx: exit
my deploy.rb is:
set :deploy_to, '/home/deploy/myrailsapp'
set :linked_files, %w{config/database.yml}
set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}
namespace :deploy do
desc 'Restart application'
task :restart do
on roles(:app), in: :sequence, wait: 5 do
execute :touch, release_path.join('tmp/restart.txt')
end
end
after :publishing, 'deploy:restart'
after :finishing, 'deploy:cleanup'
end
namespace :deploy do
after :restart, :clear_cache do
on roles(:web), in: :groups, limit: 3, wait: 10 do
# Here we can do anything such as:
# within release_path do
# execute :rake, 'cache:clear'
# end
end
end
end
i tried this tut https://www.gorails.com/deploy/ubuntu/14.04, this is my first try with capistrano.
Just create /home/deploy/myrailsapp/shared/config/database.yml file manually and adjust it.
Capistrano doesn't create (or manage) configuration file out of the box. So, you should do it manually or automate use own Capistrano scripts, Puppet, Chef, Ansible tools.
As i prefer to have my files central on the deployment server, i use this task to deploy the config files from the config dir to the linked files dir on the app server.
This uses rsync, since i use capistrano-rsync to deploy.
namespace :deploy do
task :copy_config do
on release_roles :app do |role|
fetch(:linked_files).each do |linked_file|
user = role.user + "#" if role.user
hostname = role.hostname
linked_files(shared_path).each do |file|
run_locally do
execute :rsync, "config/#{file.to_s.gsub(/.*\/(.*)$/,"\\1")}", "#{user}#{hostname}:#{file.to_s.gsub(/(.*)\/[^\/]*$/, "\\1")}/"
end
end
end
end
end
end
before "deploy:check:linked_files", "deploy:copy_config"
You can upload files using the rake task.
Add the gem to your Gemfile after setting up Capistrano, preferably in the :development group:
group :development do
gem 'capistrano', require: false
gem 'capistrano-rake', require: false
end
Аdd it to your Capfile:
require 'capistrano/rake'
# Load custom tasks from `lib/capistrano/tasks` if you have any defined
Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }
Create file lib/capistrano/tasks/setup.rake and add to it:
namespace :deploy do
namespace :check do
before :linked_files, :set_database_yml do
on roles(:app), in: :sequence, wait: 10 do
upload! 'config/database.yml', "#{shared_path}/config/database.yml"
end
end
end
end
I have set up my rails app for use with rpush. It works fine locally in development using rpush start. But now I want to deploy it to my EC2 server using capistrano-2.15.5.
Part of my deploy.rb:
after "deploy:stop", "delayed_job:stop"
after "deploy:stop", "rpush:stop"
after "deploy:start", "delayed_job:start"
after "deploy:start", "rpush:start"
after "deploy:restart", "delayed_job:restart"
after "deploy:restart", "rpush:restart"
namespace :rpush do
%w[start stop restart].each do |command|
desc "#{command} rpush deamon"
task command, roles: :app, except: {no_release: true} do
run "cd #{deploy_to}/current && bundle exec rpush #{command}"
end
end
end
Now, the problems
it starts in development environment. I tried to understand this page that tells me how to do it, but I could not.
I do not know whether the pid is stored in the /current dir or /shared dir. It should be in the shared so that the file persists between deploys
If anyone has done this (even in a different way) please tell me how to.
Or, how can I fix my cap recipe and /initializers/rpush
For Capistrano 3:
after :finished, :restart_rpush do
on roles(:web) do
within release_path do
with rails_env: fetch(:rails_env) do
execute :bundle, :exec, "rpush stop -e #{fetch(:rails_env)}"
execute :bundle, :exec, "rpush start -e #{fetch(:rails_env)}"
end
end
end
end
Then check that tmp and other directories is linked correctly:
set :linked_dirs, %w{log tmp/pids tmp/cache tmp/sockets vendor/bundle public/uploads}
I deploying rails project using capistrano 3.0
ror + nginx + unicorn
deploy is so not bad.
but server died during unicorn restart time.
1~2 second died server..
I dont know what i todo..
this is my deploy.rb source..
# -*- encoding : utf-8 -*-
# config valid only for Capistrano 3.1
lock '3.1.0'
require 'unicorn'
#set :whenever_command, "bundle exec whenever"
#require "whenever/capistrano"
set :application, 'projectname'
# Default branch is :master
# ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp }
# Default deploy_to directory is /var/www/my_app
# set :deploy_to, '/var/www/my_app'
# Default value for :scm is :git
set :scm, :git
set :repo_url, 'git#github.com:gitURL'
# Default value for :format is :pretty
set :branch, 'master'
set :deploy_via, :remote_cache
# set :format, :pretty
# Default value for :log_level is :debug
# set :log_level, :debug
# Default value for :pty is false
# set :pty, true
# Default value for :linked_files is []
# set :linked_files, %w{config/database.yml}
# Default value for linked_dirs is []
# set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}
# Default value for default_env is {}
set :default_env, { path: "/root/.rbenv/versions/2.1.0/lib/ruby/gems:/root/.rbenv/versions/2.1.0/bin:$PATH" }
#set :current_deploy_path, "DEPLOY_PATH"
# Default value for keep_releases is 5
# set :keep_releases, 5
set :ssh_options, { :forward_agent => true}
set :user, "user"
set :password, "passwod"
namespace :whenever do
task :start do
on roles(:app) do
execute("cd #{fetch :current_deploy_path}")
within release_path do
with rails_env: fetch(:rails_env) do
execute :bundle, 'exec whenever --update-crontab'
end
end
end
end
end
namespace :deploy do
desc 'Restart application'
task :restart do
on roles(:app), in: :sequence, wait: 5 do
# Your restart mechanism here, for example:
# execute :touch, release_path.join('tmp/restart.txt')
end
end
after :publishing, :restart
after :restart, :clear_cache do
on roles(:web), in: :groups, limit: 3, wait: 10 do
# Here we can do anything such as:
# within release_path do
# execute :rake, 'cache:clear'
# end
end
end
before 'deploy:assets:precompile', :link_assets
task :link_assets do
on roles(:app), :roles => :app, :except => { :no_release => true } do
execute("ln -fs #{shared_path}/database.yml #{release_path}/config/database.yml")
end
end
#before 'deploy:publishing', :kill_unicorns
task :kill_unicorns do
on roles(:app), in: :sequence, wait: 3 do
execute("if [ -f #{fetch :current_deploy_path}/tmp/pids/unicorn.pid ]; then kill -s QUIT `cat #{fetch :current_deploy_path}/tmp/pids/unicorn.pid`; fi")
end
end
task :make_unicorn do
on roles(:app), in: :sequence, wait: 3 do
execute :mkdir, '-p', "#{fetch :current_deploy_path}/tmp/pids"
execute("cd #{fetch :current_deploy_path}")
execute("if [ -f #{shared_path}/unicorn.pid ]; then kill -s QUIT `cat #{shared_path}/unicorn.pid`; fi")
within release_path do
with rails_env: fetch(:rails_env) do
execute :bundle, 'exec unicorn -D -c config/unicorn.rb -E production'
end
end
execute("cp #{fetch :current_deploy_path}/tmp/pids/unicorn.pid #{shared_path}/unicorn.pid")
end
end
# desc "Update the crontab file"
# task :update_crontab do #, :roles => :db do
# on roles(:app), in: :sequence, wait: 3 do
# execute("cd #{release_path} && bundle exec whenever --update-crontab #{application}")
# end
# end
# after 'deploy:publishing', :kill_unicorns
after 'deploy:publishing', :make_unicorn
after 'deploy:finishing', 'whenever:start'
end
and this is my deploy/production.rb
set :domain, "14.63.165.216"
set :rails_env, "production"
set :current_deploy_path, "/geuinea_pig/priday/current"
# Extended Server Syntax
# ======================
# This can be used to drop a more detailed server
# definition into the server list. The second argument
# something that quacks like a hash can be used to set
# extended properties on the server.
server '14.63.165.216', user: 'root', roles: %w{web app db}, primary: true#, my_property: :my_value
set :deploy_to, '/geuinea_pig/priday'
set :ssh_options, {
user: 'root', # overrides user setting above
# keys: %w(/home/user_name/.ssh/id_rsa),
forward_agent: false,
#auth_methods: %w(publickey password),
auth_methods: %w(password),
password: 'dPffhdPffh1!'
}
this is deploy log in capistrano log
INFO [193203be] Running /usr/bin/env if [ -f /path/shared/unicorn.pid ]; then kill -s QUIT `cat /path/shared/unicorn.pid`; fi on 14.63.165.216
DEBUG [193203be] Command: if [ -f /path/shared/unicorn.pid ]; then kill -s QUIT `cat /path/shared/unicorn.pid`; fi
#---------------------------------
#THIS TIME DIED SERVER 2~3 second
#---------------------------------
INFO [193203be] Finished in 0.227 seconds with exit status 0 (successful).
DEBUG [05a0c865] Running /usr/bin/env if test ! -d /path/releases/20140706164800; then echo "Directory does not exist '/path/releases/20140706164800'" 1>&2; false; fi on 14.63.165.216
DEBUG [05a0c865] Command: if test ! -d /path/releases/20140706164800; then echo "Directory does not exist '/path/releases/20140706164800'" 1>&2; false; fi
DEBUG [05a0c865] Finished in 0.229 seconds with exit status 0 (successful).
INFO [3cf3c052] Running /usr/bin/env bundle exec unicorn -D -c config/unicorn.rb -E production on 14.63.165.216
DEBUG [3cf3c052] Command: cd /path/releases/20140706164800 && ( PATH=/root/.rbenv/versions/2.1.0/lib/ruby/gems:/root/.rbenv/versions/2.1.0/bin:$PATH RAILS_ENV=production /usr/bin/env bundle exec unicorn -D -c config/unicorn.rb -E production )
INFO [3cf3c052] Finished in 1.061 seconds with exit status 0 (successful).
INFO [07718210] Running /usr/bin/env cp /path/current/tmp/pids/unicorn.pid /path/shared/unicorn.pid on 14.63.165.216
DEBUG [07718210] Command: cp /path/current/tmp/pids/unicorn.pid /path/shared/unicorn.pid
INFO [07718210] Finished in 0.197 seconds with exit status 0 (successful).
I would suggest a slower start on Capistrano, if you're new to it? I find it challenging. In fact, I think you're way beyond me. There are so many little things that can go wrong and the logs/output can be a bit overwhelming that I try some simpler cap tasks. I create a weird directory under the home of my deployer user and then run this:
task :dir_exists do
ask(:dir_to_test, "$home")
on roles(:all) do |host|
if test("[ -d #{fetch(:dir_to_test)} ]")
info "Phew, it's ok, the directory exists!"
else
info "Directory #{fetch(:dir_to_test)} does not exist"
end
end
end
If that runs, at least I know that I'm communicating with the server and can run things. I had big problems at first mostly having to do with the authentication. I didn't get the whole ssh-add thing. Even yesterday I had to run some new commands on my database and it took me a about two hours to figure out that my syntax was complete crap.
Anyway, the more specific you can be about what is going wrong, the more help that will be offered. By the way, do you really have a top-level directory called "/geuinea_pig/friday/current"? If all of this is capistrano, maybe save these files off and start simpler? I say that because my deploy is alot simpler, maybe you don't need all that? Also, won't backtick execution happen on the local machine (you have backtick cat /path/shared/unicorn.pid backtick)?
Anyway, good luck!
We are relatively new to using chef to deploy our applications. Currently, an odd issue we are experiencing and have yet to find a solution for relates to our bin/passenger configuration file. For some reason when the server is constructed with chef it does not exist or chef is not creating it. Maybe capistrano is not creating it... We are a bit dumbfounded by this one.
As you can see from the attached image, we know the file is not there. All of our current scripts match 4 other servers that are running successfully but for some reason this new build will not create the file. Or TBH, we are completely missing some steps. It has been some very long nights trying to get this going.
We used chef to build the server and we are using capistrano to deploy to the box
Anyone have any thoughts? Need more information? Pointers?
Our current config/deploy.rb file:
set :application, 'digest'
set :scm, :git
set :repo_url, '{omitted private repo}'
set :branch, 'experiment/cap'
set :deploy_to, '/home/apps/api'
set :deploy_via, :remote_cache
set :user, 'deploy'
set :use_sudo, false
set :rbenv_type, :system
set :rbenv_ruby, '2.1.0'
set :rbenv_path, '/opt/rbenv'
namespace :deploy do
desc 'Restart application'
task :restart do
on roles(:app), in: :sequence, wait: 5 do
execute "mkdir -p #{release_path}/tmp ; touch #{release_path}/tmp/restart.txt"
end
end
desc 'Create application symlinks'
task :symlinks do
on roles(:app), in: :sequence, wait: 5 do
execute "rm #{release_path}/config/database.yml"
execute "ln -s #{shared_path}/config/database.yml #{release_path}/config/database.yml"
execute "ln -s #{shared_path}/config/secrets.yml #{release_path}/config/secrets.yml"
execute "ln -s #{shared_path}/bin/passenger #{release_path}/bin/passenger"
end
end
after :finishing, 'deploy:cleanup'
after 'deploy:updated', 'deploy:symlinks'
end
namespace :setup do
desc 'Copy the secrets.yml and database.yml files'
task config: [ 'config/secrets.yml', 'config/database.yml' ] do |t|
on roles(:all) do
execute "mkdir -p #{shared_path}/config"
t.prerequisites.each do |file|
upload! file, "#{shared_path}/config"
end
end
end
end
In our config/deploy/staging.rb file:
set :stage, :staging
# Simple Role Syntax
# ==================
# Supports bulk-adding hosts to roles, the primary
# server in each group is considered to be the first
# unless any hosts have the primary property set.
role :app, %w{deploy#208.94.36.146}
role :web, %w{deploy#208.94.36.146}
set :rails_env, "staging"
Our staging server bin folder:
You can see the application is making it to the box with the current releases setup:
Our current application on the server:
Our current application config directory:
I'm assuming passenger isn't in the Gemfile which is would cause the binstub to not get created. Is that the issue?
I have this in my deploy.rb but I don't know how to run this command in the deployment server:
rake db:production RAILS_ENV=production
And what I have is not working. I wait for your answers. And also if you know how to start unicorn when the deploy is complete.
# Define where can Capistrano access the source repository
# set :repo_url, 'https://github.com/myuser/myapp.git'
set :scm, :git
set :repo_url, 'https://github.com/myuser/myapp.git'
# Define where to put your application code
set :deploy_to, "/home/deployer/apps/myapp"
set :pty, true
set :format, :pretty
set :rails_env, "production"
namespace :rake do
desc "Invoke rake task"
task :invoke do
run "cd #{deploy_to}/current"
run "bundle exec rake #{ENV['task']} RAILS_ENV=#{rails_env}"
end
end
you can do something like this:
%w[start stop restart].each do |command|
desc "#{command} unicorn server"
task command, roles: :app, except: {no_release: true} do
run "/etc/init.d/unicorn_#{application} #{command}"
end
end
and regard your task:
task :your_task, :roles => :app do
run "cd #{release_path}; bundle exec rake db:production RAILS_ENV=#{rails_env}"
end