我想在我的rails应用程序的初始部署中运行db:schema:load
代替db:migrate
。
这看起来相当简单,如in this stack overflow question所示,但在Capistrano 3中,他们已弃用deploy:cold
任务。初始部署与所有后续部署没有任何不同。
有什么建议吗?谢谢!
答案 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