Reputation: 20667
Bundler does an awesome job of making sure all the right gems are installed when I deploy.
However, some gems depend on binaries (eg Paperclip depends on ImageMagick, PDFKit depends on wkhtmltopdf) that may or may not be installed on the system being deployed to.
I've been bitten by this twice recently and need to figure out the best way to prevent it from happening again.
Is there a good way to ensure these external binaries and libraries are installed? Does bundler have any support for it? Should I just modify my capistrano deploy script? Should I include the binaries in my repository and make sure the gems look for them in the right place?
I can think of a few ways to approach this problem but want to know what you think works best, and why.
Upvotes: 12
Views: 1013
Reputation: 588
With Puppet, you could say something like this in your manifest:
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',
}
Upvotes: 2
Reputation: 50057
Not sure if this is applicable for you, but we use puppet for this purpose. Another (similar) alternative is chef.
So what we do is 'script' the setup of our machines, but independently of our capistrano recipes. It is not completely ideal, but it also allows a cleaner seperation: our systems guys/devops use puppet, and the rails developers use capistrano.
Upvotes: 6
Reputation: 24256
From my experience same issue with you where my servers are difference platforms (OpenSuSe, CentOS, and OSX).
I put script to install binary (yum, zypper, apt-get, etc) on capistrano script, use ruby's system() method to verify the command work. in your example of ImageMagick. It something like this
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
Upvotes: 12