11

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

这曾经是相当微不足道的,正如在这个堆栈溢出问题中看到的那样,但在 Capistrano 3 中,他们已经弃用了该deploy:cold任务。初始部署与所有后续部署没有任何不同。

有什么建议么?谢谢!

4

2 回答 2

3

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

我终于不得不深入研究 Capistrano 的源代码(以及 capistrano/bundler,以及 capistrano/rails,甚至 sshkit 和 net-ssh 来调试身份验证问题)以确定一切是如何工作的,然后我才觉得自己决定要进行哪些更改制作。我刚刚完成了这些更改,我对结果很满意:

# 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 任务只是将我的自定义 deploy:inidb 任务挂接到 deploy:migrate 之前运行。这样,模式和种子就被加载了,随后的 deploy:migrate 步骤什么也不做(安全地),因为没有新的迁移要运行。为了安全起见,我会在加载模式之前测试 schema_migrations 表是否已经存在,以防再次运行 deploy:cold。

注意:我选择使用 Puppet 创建数据库,这样我就可以避免将 CREATEDB 权限授予我的生产 postgresql 用户,但如果您希望 Capistrano 执行此操作,只需在db:schema:load,或者用 'db:setup' 替换所有三行。

于 2015-01-17T16:03:27.963 回答
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
于 2014-08-02T23:42:26.993 回答