Bundler在确保部署时安装了所有正确的gem方面做得非常出色。
然而,一些gem依赖于二进制文件(例如Paperclip依赖于ImageMagick,PDFKit依赖于wkhtmltopdf),这些二进制文件可能安装在部署到的系统上,也可能不安装。
我最近被这种情况咬了两次,需要想办法防止它再次发生。
有没有一种好的方法可以确保安装这些外部二进制文件和库?bundler对此有任何支持吗?我应该修改capistrano部署脚本吗?我是否应该将二进制文件包括在我的存储库中,并确保宝石在正确的位置查找它们?
我可以想出几种方法来解决这个问题,但我想知道你认为什么最有效,以及为什么。
根据我的经验,我的服务器是不同的平台(OpenSuSe、CentOS和OSX)。
我在capistrano脚本上放了安装二进制文件的脚本(yum、zypper、apt-get等),使用ruby的system()方法验证命令是否有效。在您的ImageMagick示例中。它有点像
desc "ImageMagick from source"
task :ImageMagick => :prepare do
d_url = "ftp://ftp.imagemagick.org/pub/ImageMagick/ImageMagick.tar.gz"
file = "ImageMagick.tar.gz"
sh("#{os_installer} install -y ghostscript-devel ghostscript-library libpng-devel libjpg-devel")
Dir.chdir('downloads') do
sh("wget -O #{file} #{d_url}")
raise "ERROR: Unable to download ImageMagick" unless File.exist?(file)
sh("tar -xzvf #{file}")
unzip_dir = Dir.glob("ImageMagick-*").first
Dir.chdir(unzip_dir) do
sh("./configure --prefix=/usr --with-x=no --disable-static --with-modules --without-perl --without-magick-plus-plus --with-quantum-depth=8")
sh("make")
sh("make install")
sh("ldconfig")
end
raise "Unable to find ImageMagick" unless system("convert --version")
end
end
不确定这是否适用于您,但我们使用puppet用于此目的。另一个(类似的)选择是厨师。
因此,我们所做的是"编写"机器的设置脚本,但与我们的capistrano配方无关。它并不完全理想,但它也允许更干净的分离:我们的系统人员/devops使用puppet,rails开发人员使用capistrano。
使用Puppet,您可以在清单中说这样的话:
package{'foo': ensure => installed, } # native (like RPM) package providing one of your binaries, installed from a repo
#then explicitly declare the dependency like this. This will be installed using 'gem install' from the default place used by gem
package{'my_gem':
ensure => installed,
require => Package['foo'],
provider => 'gem',
}