如何运行架构:加载我的rails应用程序的初始capistrano 3部署

时间:2013-12-16 21:36:52

标签: ruby-on-rails capistrano capistrano3

我想在我的rails应用程序的初始部署中运行db:schema:load代替db:migrate

这看起来相当简单,如in this stack overflow question所示,但在Capistrano 3中,他们已弃用deploy:cold任务。初始部署与所有后续部署没有任何不同。

有什么建议吗?谢谢!

2 个答案:

答案 0 :(得分:3)

我也是Capistrano的新手,并且第一次尝试使用它将Rails应用程序部署到我使用Puppet配置的生产服务器。

我终于不得不深入了解Capistrano源代码(和capistrano / bundler,以及capistrano / rails,甚至是sshkit和net-ssh来调试auth问题)以确定一切是如何运作的,直到我感到知己为自己决定了什么变化我想做。我刚刚完成了这些更改,我对结果感到满意:

# lib/capistrano/tasks/cold.rake
namespace :deploy do

  desc "deploy app for the first time (expects pre-created but empty DB)"
  task :cold do
    before 'deploy:migrate', 'deploy:initdb'
    invoke 'deploy'
  end

  desc "initialize a brand-new database (db:schema:load, db:seed)"
  task :initdb do
    on primary :web do |host|
      within release_path do
        if test(:psql, 'portal_production -c "SELECT table_name FROM information_schema.tables WHERE table_schema=\'public\' AND table_type=\'BASE TABLE\';"|grep schema_migrations')
          puts '*** THE PRODUCTION DATABASE IS ALREADY INITIALIZED, YOU IDIOT! ***'
        else
          execute :rake, 'db:schema:load'
          execute :rake, 'db:seed'
        end
      end
    end
  end

end

deploy:cold任务仅挂钩我的自定义部署:inidb任务在deploy:migrate之前运行。这样,架构和种子就会被加载,并且随后的deploy:migrate步骤不会(安全地)执行任何操作,因为没有新的迁移要运行。为安全起见,我在加载模式之前测试schema_migrations表是否已经存在,以防再次运行deploy:cold。

注意:我选择使用Puppet创建数据库,因此我可以避免将CREATEDB权限授予我的生产postgresql用户,但如果您希望Capistrano执行此操作,只需添加“execute:rake,'db:create' “在db:schema之前:加载,或用'db:setup'替换所有三行。

答案 1 :(得分:2)

您必须将deploy:cold定义为正常部署任务的副本,但使用deploy:db_load_schema而不是deploy:migrations。例如:

desc 'Deploy app for first time'
task :cold do
  invoke 'deploy:starting'
  invoke 'deploy:started'
  invoke 'deploy:updating'
  invoke 'bundler:install'
  invoke 'deploy:db_load_schema' # This replaces deploy:migrations
  invoke 'deploy:compile_assets'
  invoke 'deploy:normalize_assets'
  invoke 'deploy:publishing'
  invoke 'deploy:published'
  invoke 'deploy:finishing'
  invoke 'deploy:finished'
end

desc 'Setup database'
task :db_load_schema do
  on roles(:db) do
    within release_path do
      with rails_env: (fetch(:rails_env) || fetch(:stage)) do
        execute :rake, 'db:schema:load'
      end
    end
  end
end

独立运行deploy:db_schema_load任务可能更好,因为默认deploy中包含的任务可能会随着时间的推移而发生变化。

我实际上使用db:setup进行全新部署,因为它在创建表后为数据库播种:

desc 'Setup database'
task :db_setup do
  ...
        execute :rake, 'db:setup'
  ...
end