【问题标题】:How to run schema:load on the initial capistrano 3 deploy of my rails app如何运行模式:加载我的 rails 应用程序的初始 capistrano 3 部署
【发布时间】:2013-12-16 21:36:51
【问题描述】:

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

这曾经是相当微不足道的,如 in this stack overflow question 所见,但在 Capistrano 3 中,他们已弃用 deploy:cold 任务。初始部署与所有后续部署没有任何不同。

有什么建议吗?谢谢!

【问题讨论】:

    标签: ruby-on-rails capistrano capistrano3


    【解决方案1】:

    我也是 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 执行此操作,只需添加“execute :rake, 'db:create' " 在 db:schema:load 之前,或将所有三行替换为 'db:setup'。

    【讨论】:

    • 我不知道他们为什么在 Capistrano 3 中删除了 deploy:cold - 这对我来说似乎仍然是正确的方法。但我很高兴它促使我根据自己的需要定制自己的版本,我很高兴我现在和我一样了解系统的内部工作原理。
    • 什么是“portal_production”?
    • 我的生产数据库的名称。
    【解决方案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
    

    【讨论】:

    • 感谢您的建议;这让我对自己的直觉感到更舒服,即重新创建 deploy:cold 是要走的路。我在你的下面发布了我自己的版本。
    猜你喜欢
    • 1970-01-01
    • 2017-06-05
    • 1970-01-01
    • 2016-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多