Creating Your Own Gem Server

Update – August 1, 2008

This page remains one of my most active pages for Google Searches. A number of folks want to run their own gem server, and for good reason.

Unfortunately it’s outdated and has been for a while, and I’ve been too lazy to update it.

I also hate for you to leave with outdated information – so please check out the updated information about the commands that are now built into gem and available for facilitating running your own gem distribution site.

I’ve been hand updating gems for too long on my servers, but I have been hesitant to do anything more automated as long as my systems were updating against Rubyforge has been down more than once when I really needed to update something, and I don’t want to create an automated dependency on a third-party service

So before I automate things, I needed a way to point to my own gem server. Which thankfully, it turns out, that it’s not all that hard to do so (it’s harder than it has to be, and man oh man is the gem cache a pain in the rear). This all assumes that you already had rubygems installed on the boxes that you are moving over to point to your own server. (This also assumes that you use a Linux/Unix server, I’m sure all this works on a Windows server, but I haven’t tested one and honestly don’t care).

Setting up your server

  1. You need a web server. (yes I know you can run gem_server, but get a real one). You are on your own for that one. You also need a rubygems install on that box. You are also on your own for bootstrapping rubygems on that box and any other ones.
  2. Decide where you will put your gems (say in a “mycoolgems” directory off the docroot for your webserver)
  3. $ mkdir [docroot]/mycoolgems/gems
  4. Copy your .gem files that you want to host to $ [docroot]/mycoolgems/gems
  5. Rubygems installed a "index_gem_repository.rb" ruby script in your path. (well probably in your path, it’s in /usr/bin on my systems). You want to run this to generate a yaml-based index of your gems. (appropriately named “yaml” – and a compressed yaml.Z) e.g. index_gem_repository.rb -d [docroot]/mycoolgems

Pointing your systems to your own server

Setting up the server is the easy part. The harder part is pointing all your boxes to your own server. And only your own server. You’d think that one neat thing about the 0.9.2 rubygems release is that it includes a “gem sources” command to theoretically add and remove gem sources that your boxes would look at, but you’d be wrong. Because you can’t get rid of the base source of without modifying the sources gem or the sources distribution on your own box. You can theoretically modify [lib/ruby]/gems/1.8/gems/sources-0.0.1/lib/sources.rb and change:

module Gem  @sources = [""]  def self.sources    @sources  endend


@sources = ["http://yourserver.yourdomain"]

However, that customization is likely going to get blown away the next time you update rubygems with a gem update --system – because the sources gem is built by the rubygems update. So what do you do? Build your own gem update.

  1. Download the RubyGems source
  2. Edit pkgs/sources/lib/sources.rb to point to your own server
  3. Rebuild the gem by issuing a rake package – which will build the rubygems update gem with your source changes (in pkg/ – in my case pkg/rubygems-update-0.9.2.gem)
  4. Copy this gem to your gem server’s gems directories (and rebuild the yaml index as appropriate)
  5. On your other servers – clear out [lib/ruby]/gems/1.8/cache
  6. Remove the [lib/ruby]/gems/1.8/source_cache
  7. Run gem update --system --source http://yourserver.yourdomain

That’s All Folks (probably)

Voila! You just managed to point your server to your own gem server! Install away.

It’s good to keep one box pointed to – and take advantage of the new “gem outdated” command to keep track of changes in your installed gems that have been deployed to rubyforge.

[Updated: April 19, 2007 Thanks to Jim Weirich for pointing out that the index script should actually be index_gem_repository.rb and NOT generate_yaml_index.rb. generate_yaml_index.rb is a holdover from earlier rubygems versions]