gemサイトのローカルミラーの正しい作り方
とあるインターネットにつなげないサーバでRails環境をセットアップする必要があったので、作業用WindowsPCにgem配布サイト(http://rubygems.org)のローカルミラーを作成することにした。
ローカルミラーの作成方法はネット検索でいくつか書かれているのを見つけたが、どれも成功しなかったので正しい作成方法を記載しておく。
まずミラーするサイトと保存するディレクトリを定義する設定ファイルを作成する。
[HOME]/.gemmirrorrc に作成。fromにサイトURL、toに保存先のディレクトリを書く。保存先ディレクトリは予め作成しておくこと。
[HOME]はWindowsではC:\Document and Settings\[user]となる。
--- - from: http://rubygems.org/ to: C:\[path_to_download]
次にミラーするコマンド、gem mirrorを実行。gem help mirrorでコマンドのヘルプを見ると--config-fileオプションでgemmirrorrcファイルを指定できるらしくなっているけど、これはうまく動かなかったので上の手順のようにちゃんとホームディレクトリに作成するように。
> gem mirror
2,3日実行しっぱなしにしておくとすべてのgemファイルが[path_to_download]/gemsにダウンロードされ、gem mirrorコマンドは完了する。
しかし必要なファイルはこれだけではない。他の必要なファイルは手動でダウンロードしなければならなかった。
まず、[path_to_download]直下に下記ファイルをダウンロードした。
- http://rubygems.org/latest_specs.4.8.gz
- http://rubygems.org/Marshal.4.8.Z
- http://rubygems.org/specs.4.8.gz
- http://rubygems.org/yaml
次に[path_to_download]/quickディレクトリを作成し下記ファイルをダウンロードした。
そして[path_to_download]/quick/quick/Marshal.4.8 ディレクトリを作成しここにhttp://rubygems.org/quick/Marshal.4.8/以下のgemspecファイルをすべてダウンロードする必要がある。
数が多いので一つ一つ手動でダウンロードしていくのは無理、適当にスクリプトを書いて自動化しないと現実的でない。
gemspecファイルのファイル名はどうやら[gemファイル名から拡張子抜いたもの].gemspec.rzというようになるようだ。
たとえばgemファイルが rubyzip2-2.0.0.gemならgemspecファイルはrubyzip2-2.0.0.gemspec.rzとなる。
適当に下記のようにスクリプトを書いてみてダウンロードさせてみた。[path_to_download]直下に保存して実行。これもかなり時間がかかる。
GEMSITE_DOMAIN='rubygems.org' GEMSITE_PORT=80 #-- require 'net/http' def fetch(uri_str) response = Net::HTTP.get_response(URI.parse(uri_str)) case response when Net::HTTPSuccess then response when Net::HTTPRedirection then fetch(response['Location']) else return nil end end Dir.foreach('gems') do |gem_filename| next if gem_filename == '.' || gem_filename == '..' gem_name = File.basename gem_filename, '.gem' gemspec_filename = gem_name + '.gemspec.rz' url = "http://#{GEMSITE_DOMAIN}:#{GEMSITE_PORT}" + '/quick/Marshal.4.8/' + gemspec_filename puts "Downloading..#{url}" res = fetch(url) if res.nil? puts " Error: #{url}" next end File.open('quick/Marshal.4.8/' + gemspec_filename, 'wb') do |io| io.write(res.body) end end
すべてダウンロードして10.9GBになる。
あとは[path_to_download]をサイトのドキュメントルートとするようにhttpdを立てて、gemをインストールするクライアントの方からは下記のように--sourceオプションでソースサイトを指定する。
> gem install rubyzip --source http://your.rubygems.mirror
--sourceオプションをつけるのが面倒ならば下記のように[HOME]/.gemrcを作成するとデフォルトで設定したミラーサイトにアクセスしてくれる。
:sources: - http://your.rubygems.mirror
ちなみに関係無い話だが、http://rubygems.orgではgemファイルはAWSのCloudFrontに、gemspecファイルはS3(CloudFrontではない)に置かれていてrubygems.orgからGETしようとすると上記のAWSの方にリダイレクトされた。