Capistrano - can't deploy my database.yml

When I try to deploy my app with capistrano, I'll get this error:

failed: "sh -c 'cp /var/www/my_app/releases/20120313115055/config/database.staging.yml /var/www/my_app/releases/20120313115055/config/database.yml'" on IP_ADDR

My database.yml ie empty, database.staging.yml:

production:
  adapter: mysql2
  encoding: utf8
  reconnect: false
  database: my_db
  pool: 15
  username: my_user_name
  password: my_pass
  host: localhost

in the /confing/deploy are files "production" "staging"

What am I missing here/where should I look for a failure? The credentials to database on the server should be right.

EDIT - here is my deploy

set :application, "my_app"
set :repository, "https://IP_ADDR/svn/my_app"

set :scm, :subversion
set :scm_username, 'my_name'
set :scm_password, 'my_pass'

default_run_options[:pty] = true

set :user, "my_name"
set :domain, 'IP_ADDR'

set :deploy_to, "/var/www/my_app"

set :use_sudo, false
set :deploy_via, :remote_cache
#set :keep_releases, 1

set :rails_env, 'production'

role :web, domain
role :app, domain
role :db,   domain, :primary => true # This is where Rails migrations will run

namespace :deploy do

    task :build_gems, :roles => :app do
        desc "Building gems"
        run "cd #{release_path} && bundle install --deployment"
    end

    task :migrations do
        desc "Migrating database"
        run "cd #{release_path} && rake db:migrate RAILS_ENV=production"
    end

    [:start, :stop].each do |t|
        desc "#{t} task is a no-op with passenger"
        task t, :roles => :app do ; end
    end

    desc "Restarting passenger with restart.txt"
    task :restart, :roles => :app, :except => { :no_release => true } do
        run "touch #{release_path}/tmp/restart.txt"
    end

    after "deploy:update_code", "deploy:build_gems", "db:copy_configuration", "config:copy", "deploy:migrations", "deploy:cleanup"
    after "deploy:update", "bluepill:copy_config", "bluepill:restart"
end

namespace :db do
    task :copy_configuration do
        run "cp #{release_path}/config/database.staging.yml #{release_path}/config/database.yml"
    end
end

namespace :config do
    task :copy do
        run "cp #{release_path}/config/config.staging.yml #{release_path}/config/config.yml"
    end
end

namespace :bluepill do
  desc "Restart bluepill process"
  task :restart, :roles => [:app] do
    run "#{release_path}/script/delayed_job stop"
    sudo "/etc/init.d/bluepill.sh restart"
  end

  #desc "Load bluepill configuration and start it"
  ##task :start, :roles => [:app] do
   # sudo "/etc/init.d/bluepill.sh start"
  #end

  desc "Prints bluepills monitored processes statuses"
  task :status, :roles => [:app] do
    sudo "bluepill status"
  end

  desc "Copy config"
  task :copy_config, :roles => [:app] do
    run "cp #{release_path}/config/bluepill/configuration.rb /srv/script/bluepill.rb"
  end
end

The problem:

cp: cannot stat `/var/www/my_app/releases/20120313144907/config/database.staging.yml': No such file or directory

Answers


I'm not sure how to solve your problem. It looks like database.staging.yml is not being deployed, so there's nothing for it to copy over.

I think there's a better workflow, though. Things like settings and database configs do not typically change between deployments, so those things can go in the shared folder of all the capistrano releases. Typically, you don't want your database.yml to be in your repo either since it's sensitive information. You can satisfy both of these things by excluding config/database.yml in your .gitignore.

This requires you to do a one time set up on your servers. You need create a database.yml at your_app_path/shared/config. Shared is a sibling to current and releases.

Your deploy.rb should have a task that symlinks the newly deployed release's database.yml to the on in the shared directory. Like this:

before "deploy:assets:precompile" do
  run ["ln -nfs #{shared_path}/config/settings.yml #{release_path}/config/settings.yml",
       "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml",
       "ln -fs #{shared_path}/uploads #{release_path}/uploads"
  ].join(" && ")
end

This means that your repo will contain no database.yml files. Since they are probably already in your repo. You'll have to git rm them, commit. Add them to the .gitignore and commit that.


In Capistrano 3, linking files is built-in. John's answer is simply:

  • In the shared/ folder create config/database.yml
  • In config/deploy.rb use this line

    set :linked_files, fetch(:linked_files, []).push('config/database.yml')
    

This does what John was saying.


If you don't need to "reference application objects or methods"(1) during precompile then you might be OK with setting config.assets.initialize_on_precompile to false in config/application.rb


Need Your Help

SQLCe local db in temp- path in connectionstring?

c# sql-server-ce connection-string

I have SQL Ce db in my app, which is included in my app directory. While debugging its OK, but when published and run with setup.exe, it retrieves "file not found" in temporary directory the app is...

Is the Singleton design pattern built into any frameworks?

c# java frameworks singleton

Using a Singleton class guarantees one instance of a class to give control to the programmer. Really useful.