Capistrano - can't deploy my database.yml

10,176

Solution 1

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.

Solution 2

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.

Share:
10,176
user984621
Author by

user984621

Updated on June 05, 2022

Comments

  • user984621
    user984621 almost 2 years

    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
    
  • tehfoo
    tehfoo about 11 years
    we did this, but included a database.yml.example in config, which developers can use to get going locally without having to guess at the database.yml settings
  • vajapravin
    vajapravin about 11 years
    I think current/config/database.yml is linked to shared/config/database.yml If shared/config/database.yml is missing it will give you 'No such file or directory'. We can create it manually to shared/config/database.yml and deploy it. This stuff works here.
  • Matthias
    Matthias about 8 years
    Sorry, why does your deploy.rb script mention settings.yml?
  • Francisco Quintero
    Francisco Quintero over 7 years
    This is it. Thanks