My Capistrano deployment does not set the RAILS_ENV variable when running the bundle command. I don't understand why.
My Gemfile is :
source 'https://rubygems.org'
ruby '2.1.3'
gem 'capistrano', '~> 3.2.1'
gem 'capistrano-rails', '~> 1.1.1'
My deploy.rb :
set :stage, :production
set :rails_env, 'production'
set :bundle_flags, '--deployment'
set :bundle_env_variables, { rails_env: "production" }
namespace :sphinx do
desc "Index Sphinx"
task :index do
on roles(:app) do
within release_path do
execute :rake, "rake ts:index"
end
end
end
When running :
➜ ansible-sharetribe git:(master) ✗ bin/cap production sphinx:index --trace
** Invoke production (first_time)
** Execute production
** Invoke load:defaults (first_time)
** Execute load:defaults
** Invoke bundler:map_bins (first_time)
** Execute bundler:map_bins
** Invoke deploy:set_rails_env (first_time)
** Execute deploy:set_rails_env
** Invoke deploy:set_rails_env
** Invoke sphinx:index (first_time)
** Execute sphinx:index
INFO[3ca70ab5] Running bundle exec rake rake ts:index on www.myapplication.com
cap aborted!
SSHKit::Runner::ExecuteError: Exception while executing on host www.myapplication.com: rake exit status: 1
rake stdout: Nothing written
rake stderr: Digest::Digest is deprecated; use Digest
rake aborted!
NameError: uninitialized constant Annotate
If I write :
execute :rake, "rake ts:index RAILS_ENV=production"
it works. Why is RAILS_ENV=production not set automatically?
You can use this syntax in your task
execute :rake, "rake ts:index", "RAILS_ENV=#{fetch :rails_env}"
I have the same problem.
I ran rake secret and got "NameError: uninitialized constant Annotate" error.
After i set RAILS_ENV=production, it worked like charm.
I dont know why RAILS_ENV wasnt set but BTW thanks so much.
Saved me a lot of time
Related
When I making migration db Cassandra with command:
es#es:~/server-new$ rake ks2:migrate_old
After this I get error:
rake aborted!
SystemStackError: stack level too deep
Tasks: TOP => ks2:migrate_old => ks2:set_keyspace2 => ks2:configure2 => environment
(See full trace by running task with --trace)
When I start command: rake ks2:migrate_old --trace
I get error:
** Invoke ks2:migrate_old (first_time)
** Invoke ks2:set_keyspace2 (first_time)
** Invoke ks2:configure2 (first_time)
** Invoke environment (first_time)
** Execute environment
rake aborted!
SystemStackError: stack level too deep
/home/es/.rvm/gems/ruby-2.0.0-p353/gems/rake-10.4.2/lib/rake/task.rb:183
Tasks: TOP => ks2:migrate_old => ks2:set_keyspace2 => ks2:configure2 => environment
How to make migration work?
I'm using a capistrano 3 task that should work, but am getting the error:
> cap staging deploy --trace
** Invoke staging (first_time)
** Invoke use_rvm (first_time)
** Execute use_rvm
** Execute staging
** Invoke load:defaults (first_time)
** Execute load:defaults
cap aborted!
Task Argument Error
/Users/stevenspiel/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rake-10.4.2/lib/rake/task_manager.rb:109:in `resolve_args_with_dependencies'
/Users/stevenspiel/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rake-10.4.2/lib/rake/task_manager.rb:75:in `resolve_args'
/Users/stevenspiel/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rake-10.4.2/lib/rake/task_manager.rb:27:in `define_task'
/Users/stevenspiel/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rake-10.4.2/lib/rake/task.rb:365:in `define_task'
/Users/stevenspiel/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/rake-10.4.2/lib/rake/dsl_definition.rb:66:in `task'
config/deploy.rb:65:in `<top (required)>'
...
the task is straightforward:
set :backup_to, '/home/deployer/app/db_backups'
desc 'Backup the remote production database'
task :backup_database, roles: :db, only: { primary: true } do
run "mkdir -p #{backup_to}" # create backup folder unless already exists
filename = "#{backup_to}/app_#{Time.now.strftime '%Y%m%d%H%M%S'}.sql.gz"
# Check if we've got database config
database_config = File.join(deploy_to, '/current/config/database.yml')
if remote_file_exists?(database_config)
text = capture("cat #{database_config}")
# `capture` is returning some bad whitespace that YAML::load can't handle.
# This strips out whitespace except for innocuous spaces and newlines.
text.gsub!(/[^\n \S]/, '')
config = YAML::load(text)[rails_env]
on_rollback { run "rm #{filename}" } # if migration rolls back, removes backup
run "pg_dump -U #{config['username']} #{config['database']} -W -h #{config['host']} | gzip --best > #{filename}" do |ch, stream, out|
ch.send_data "#{config['password']}\n" if out =~ /^Password:/
end
else
logger.debug('[BackupDatabase] No configuration file was found.')
end
end
before 'deploy:migrate', :backup_database if rails_env == 'staging'
And the error is coming from the task declaration:
task :backup_database, roles: :db, only: { primary: true } do
What is wrong with it?
EDIT
Thanks to basia's suggestion, I ended up doing this:
task :backup_database do
on roles(:app), except: { primary: true } do
...
end
end
You're using Capistrano 2 syntax and for Capistrano 3 the syntax is different than 2, have a look https://semaphoreapp.com/blog/2013/11/26/capistrano-3-upgrade-guide.html. Your code should look more like that (not tested):
task :backup_database do
roles(:db) do
.....
on
end
Or downgrade to Cap 2 :)
The way I set up environment variables is like it was outlined here.
In other words I created a config/app_env_vars.rb file and put:
unless Rails.env.production?
ENV['DB_PASSWORD'] = 'password'
ENV['DB_USERNAME'] = 'username'
end
puts 'ECHO app_env_vars.rb'
In config/environment.rb I put:
app_env_vars = File.join(Rails.root, 'config', 'app_env_vars.rb')
load(app_env_vars) if File.exists?(app_env_vars)
puts "ECHO environment.rb"
right before Rails.application.initialize!
In database.yml:
development:
adapter: postgresql
encoding: unicode
database: my_app_development
host: localhost
pool: 5
password: <%= ENV['DB_PASSWORD'] %>
test:
adapter: postgresql
encoding: unicode
database: my_app_test
host: localhost
pool: 5
password: <%= ENV['DB_PASSWORD'] %>
When I run tasks such as bundle exec rake db:migrate and bundle exec rake db:reset it works fine but when I run bundle exec rake db:migrate:reset it will fail displaying:
fe_sendauth: no password supplied
.
.
.
Couldn't drop my_app_development
fe_sendauth: no password supplied
.
.
.
Couldn't drop my_app_test
fe_sendauth: no password supplied
ECHO app_env_vars.rb
ECHO environment.rb
Usually when I run bundle exec rake db:migrate (and db:drop) it will first display the ECHO parts and then do the task and out put the log. But in the case of the db:migrate:reset it won't initialize the environment variables until after the task.
When in database.yml I put the actual passwords rather than the env variables then the
db:migrate:reset works with no problem.
Here is rake db:migrate:reset with --trace option
** Invoke db:migrate:reset (first_time)
** Invoke db:drop (first_time)
** Invoke db:load_config (first_time)
** Execute db:load_config
** Execute db:drop
fe_sendauth: no password supplied
.
. # gem trace stuff...
.
Couldn't drop my_app_development
fe_sendauth: no password supplied
.
. # gem trace stuff...
.
Couldn't drop my_app_test
** Invoke db:create (first_time)
** Invoke db:load_config
** Execute db:create
fe_sendauth: no password supplied
.
. # gem trace stuff...
.
Couldn't create database for {"adapter"=>"postgresql", "encoding"=>"unicode", "database"=>"my_app_development", "host"=>"localhost", "pool"=>5, "password"=>nil}
fe_sendauth: no password supplied
.
. # gem trace stuff...
.
Couldn't create database for {"adapter"=>"postgresql", "encoding"=>"unicode", "database"=>"my_app_test", "host"=>"localhost", "pool"=>5, "password"=>nil}
** Invoke db:migrate (first_time)
** Invoke environment (first_time)
** Execute environment
ECHO app_env_vars.rb
ECHO environment.rb
** Invoke db:load_config
** Execute db:migrate
** Invoke db:_dump (first_time)
** Execute db:_dump
** Invoke db:schema:dump (first_time)
** Invoke environment
** Invoke db:load_config
** Execute db:schema:dump
** Execute db:migrate:reset
Here is the --trace for rake db:reset
** Invoke db:reset (first_time)
** Invoke environment (first_time)
** Execute environment
ECHO app_env_vars.rb
ECHO environment.rb
** Invoke db:load_config (first_time)
** Execute db:load_config
** Execute db:reset
** Invoke db:drop (first_time)
** Invoke db:load_config
** Execute db:drop
** Invoke db:setup (first_time)
** Invoke db:schema:load_if_ruby (first_time)
** Invoke db:create (first_time)
** Invoke db:load_config
** Execute db:create
** Invoke environment
** Execute db:schema:load_if_ruby
** Invoke db:schema:load (first_time)
** Invoke environment
** Invoke db:load_config
** Execute db:schema:load
-- enable_extension("plpgsql")
-> 0.0772s
-- create_table("users", {:force=>true})
-> 0.0795s
-- add_index("users", ["email"], {:name=>"index_users_on_email", :unique=>true, :using=>:btree})
-> 0.0406s
-- initialize_schema_migrations_table()
-> 0.0829s
** Invoke db:structure:load_if_sql (first_time)
** Invoke db:create
** Invoke environment
** Execute db:structure:load_if_sql
** Invoke db:seed (first_time)
** Execute db:seed
** Invoke db:abort_if_pending_migrations (first_time)
** Invoke environment
** Execute db:abort_if_pending_migrations
** Execute db:setup
In the case of db:reset the ** Execute environment part is done before any executions, while with db:migrate:reset the ** Execute environment is done after a few executions
The reason why this setup (setting env variables in a file then load them trough environment.rb) doesn't work is because active record can be used outside rails therefore now every task runs with initialized rails environment.
A better solution is to use gems like figaro or dot-env which will load with every rake task. How exactly is that done with those gems I am not sure but if I get into it and find out I'll post here.
I'm in the midst of upgrading my Rails app to Capistrano 3 and I seem to have hit a wall.
When running cap staging deploy, I get this error:
** Invoke staging (first_time)
** Execute staging
** Invoke load:defaults (first_time)
** Execute load:defaults
** Invoke bundler:map_bins (first_time)
** Execute bundler:map_bins
** Invoke deploy:set_rails_env (first_time)
** Execute deploy:set_rails_env
** Invoke deploy:set_rails_env
** Invoke deploy (first_time)
** Execute deploy
** Invoke deploy:starting (first_time)
** Execute deploy:starting
** Invoke deploy:check (first_time)
** Execute deploy:check
** Invoke git:check (first_time)
** Invoke git:wrapper (first_time)
** Execute git:wrapper
** Execute git:check
** Invoke deploy:check:directories (first_time)
** Execute deploy:check:directories
** Invoke deploy:check:linked_dirs (first_time)
** Execute deploy:check:linked_dirs
** Invoke deploy:check:make_linked_dirs (first_time)
** Execute deploy:check:make_linked_dirs
** Invoke deploy:check:linked_files (first_time)
** Execute deploy:check:linked_files
** Invoke deploy:set_previous_revision (first_time)
** Execute deploy:set_previous_revision
** Invoke deploy:started (first_time)
** Execute deploy:started
** Invoke deploy:check_revision (first_time)
** Execute deploy:check_revision
cap aborted!
SSHKit::Runner::ExecuteError: Exception while executing on host %HIDDEN_HOST_NAME%: undefined local variable or method `branch' for #<SSHKit::Backend::Netssh:0x007fe8958826f8>
config/deploy.rb:35:in `block (3 levels) in <top (required)>'
/Users/user/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/sshkit-1.5.1/lib/sshkit/backends/netssh.rb:54:in `instance_exec'
/Users/user/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/sshkit-1.5.1/lib/sshkit/backends/netssh.rb:54:in `run'
/Users/user/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/sshkit-1.5.1/lib/sshkit/runners/parallel.rb:13:in `block (2 levels) in execute'
NameError: undefined local variable or method `branch' for #<SSHKit::Backend::Netssh:0x007fe8958826f8>
config/deploy.rb:35:in `block (3 levels) in <top (required)>'
/Users/user/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/sshkit-1.5.1/lib/sshkit/backends/netssh.rb:54:in `instance_exec'
/Users/user/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/sshkit-1.5.1/lib/sshkit/backends/netssh.rb:54:in `run'
/Users/user/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/sshkit-1.5.1/lib/sshkit/runners/parallel.rb:13:in `block (2 levels) in execute'
Tasks: TOP => deploy:check_revision
The deploy has failed with an error: #<SSHKit::Runner::ExecuteError: Exception while executing on host %HIDDEN_HOST_NAME%: undefined local variable or method `branch' for #<SSHKit::Backend::Netssh:0x007fe8958826f8>>
** Invoke deploy:failed (first_time)
** Execute deploy:failed
Here is my Capfile:
# Load DSL and Setup Up Stages
require 'capistrano/setup'
# Includes default deployment tasks
require 'capistrano/deploy'
require 'capistrano/bundler'
require 'capistrano/rails'
require 'capistrano/rails/migrations'
require 'capistrano/rails/assets'
require 'new_relic/recipes'
# Loads custom tasks from `lib/capistrano/tasks' if you have any defined.
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }
Rake.application.options.trace = true
Rake.application.options.backtrace = true
Here is deploy.rb
# config valid only for Capistrano 3.1
lock '3.2.1'
set :application, "%HIDDEN%"
set :repo_url, "%HIDDEN%"
ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp }
# I've also tried simply set :branch, "master" but same result
set :git_enable_submodules, 1
set :bundle_flags, "--deployment --verbose"
set :rails_env, "production"
set :pty, true
set :linked_files, %w{config/database.yml}
set :linked_dirs, %w{bin log tmp vendor/bundle public/system}
set :config_files, %w{database.example.yml}
And staging.rb
location = "%HIDDEN_HOST_NAME%"
role :app, location
role :web, location, no_release: true
role :db, location
server location, roles: %w{web app db}
set :ssh_options, {
user: "deploy",
forward_agent: true,
}
Per http://capistranorb.com/documentation/getting-started/cold-start/, I can run cap staging check_write_permissions and cap staging git:check just fine. No errors there. Running cap production deploy produces the same error.
Any ideas? Thanks in advance!
It turned out I had a task that was referring to #{branch}. This worked in Cap 2 but not Cap 3 apparently.
This was the fix:
desc "Make sure local git is in sync with remote."
task :check_revision do
branch = fetch(:branch) # <--- This line fixed it
on roles(:app) do
unless ENV["IGNORE_GIT_SYNC"]
unless `git rev-parse HEAD` == `git rev-parse origin/#{branch}`
puts "WARNING: HEAD is not the same as origin/#{branch}"
puts "Run `git push` to sync changes."
puts "(set IGNORE_GIT_SYNC=1 to ignore this)"
exit
end
end
end
end
Postgres 9.3, Ruby 2.1.0
rake db:create isn't making a test database. I already have a production database. I tried using RAILS_ENV=test rake db:create to force it but it returns "test database is not configured.
My database.yml ->
development:
adapter: postgresql
database: app_prod
host: localhost
test: &test
adapter: postgresql
database: app_test
host: localhost
cucumber:
<<: *test
production:
adapter: postgresql
database: app_prod
host: localhost
So it is configured. I also tried just using a console createdb app_test to create my test database but I receive the same error when I try to run rake db:test:prepare.
Anyone have any ideas?
this is --trace on db:create:all
** Invoke db:create:all (first_time)
** Invoke db:load_config (first_time)
** Execute db:load_config
** Execute db:create:all
rake aborted!
undefined method `[]' for nil:NilClass
/Users/username/.rvm/rubies/ruby-2.1.0/lib/ruby/gems/2.1.0/gems/activerecord-4.0.3/lib/active_record/tasks/database_tasks.rb:189:in `block in each_local_configuration'
this is trace on db:test:prepare
** Invoke db:test:prepare (first_time)
** Invoke db:load_config (first_time)
** Execute db:load_config
** Execute db:test:prepare
** Invoke db:test:load (first_time)
** Invoke db:test:purge (first_time)
** Invoke environment (first_time)
** Execute environment
** Invoke db:load_config
** Execute db:test:purge
rake aborted!
undefined method `[]' for nil:NilClass
/Users/username/.rvm/rubies/ruby-2.1.0/lib/ruby/gems/2.1.0/gems/activerecord-4.0.3/lib/active_record/tasks/database_tasks.rb:137:in `purge'
Try running this in console
ActiveRecord::Base.configurations
You should get your database configurations.
Line 3 in this method(Line 189 in github) is failing in your case because configuration is nil
def each_local_configuration
ActiveRecord::Base.configurations.each_value do |configuration|
next unless configuration['database']
if local_database?(configuration)
yield configuration
else
$stderr.puts "This task only modifies local databases. #{configuration['database']} is on a remote host."
end
end
end