使用资产管道优化将Rails应用部署到多台服务器

问题描述 投票:5回答:3

我正在多服务器环境中部署Rails应用程序。该应用程序使用资产管道,并且从s3开始提供资产。如果我在部署到的每台服务器上运行asset:precompile,则一切正常(在每个框中生成所需的asset / manifest.yml)。

问题是,这感觉效率很低。我尝试将其中一台服务器指定为主服务器,并且仅在该服务器上运行资产:precompile。现在的问题是其他服务器没有资产/manifest.yml的副本。

思考解决方案将涉及找出在所有盒子上共享生成的资产/manifest.yml文件的最简单方法。

其他人如何处理这种情况?

感谢您的帮助。

ruby-on-rails ruby deployment capistrano asset-pipeline
3个回答
1
投票

最终通过编写此上限任务解决了这个问题:

task :assets_precompile, { on_no_matching_servers: :continue, only: { primary: true } } do
  transaction do
    on_rollback do
      notification.exception_deploy
    end

    run "cd #{current_release} && RAILS_ENV=#{stage} rake assets:precompile"

    # sync manifest.yml
    download("#{current_release}/public/assets/manifest.yml", "/tmp/manifest.yml")

    find_servers().each do |current_server|
      run_locally "ssh app@#{current_server.host} 'mkdir -p #{current_release}/public/assets'"
      run_locally "scp /tmp/manifest.yml app@#{current_server.host}:#{current_release}/public/assets/manifest.yml"
    end
  end
end

似乎有点a,但可以完成工作。我们不想在本地进行预编译。


0
投票

更好的建议可能是升级到Capistrano 3(上周发布),它通常更快,并且rails插件更好地模块化。在rails/assets gem中找到的capistrano-rails扩展名很简单(它并不能满足您的需要,但是更简单)。而且,您可以使用gem来进行迁移支持,并将资产管道任务复制/修改到您的项目中,并对其进行修改以执行所需的任何操作。

例如,在Capistrano 3中,您还可以通过roles(:web)获取服务器列表,该列表将返回服务器对象列表,因此您可以编写任务,仅限于一台可以访问其他服务器,并通过LAN(或WAN)执行rsync,以将您的资产同步到其他计算机。


0
投票
task :copy_assets_manifest do
  next unless roles(:web, :app).count > 1
  manifest_contents, manifest_name = nil, nil
  assets_path = release_path.join('public', fetch(:assets_prefix))

  on roles(fetch(:assets_roles)), primary: true do
    manifest_name = capture(:ls, assets_path.join('manifest*')).strip
    manifest_contents = download! assets_path.join(manifest_name)
  end
  on roles(:app) do
    execute :rm, '-f', assets_path.join('manifest*')
    upload! StringIO.new(manifest_contents), assets_path.join(manifest_name)
  end
end

在计算机上编译资产并下载manifest.json,该清单负责获取计算机上的最新资产,并将其上载到所有计算机。

© www.soinside.com 2019 - 2024. All rights reserved.