{"id":13819652,"url":"https://github.com/geminabox/geminabox","last_synced_at":"2025-05-12T13:32:36.857Z","repository":{"id":37285400,"uuid":"463074","full_name":"geminabox/geminabox","owner":"geminabox","description":"Really simple rubygem hosting","archived":false,"fork":false,"pushed_at":"2025-03-05T20:50:25.000Z","size":604,"stargazers_count":1507,"open_issues_count":6,"forks_count":317,"subscribers_count":25,"default_branch":"master","last_synced_at":"2025-04-23T17:09:13.887Z","etag":null,"topics":["gem","hacktoberfest","ruby","rubygems"],"latest_commit_sha":null,"homepage":"https://tomlea.co.uk/p/gem-in-a-box","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/geminabox.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"MIT-LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2010-01-07T23:05:13.000Z","updated_at":"2025-04-18T08:50:25.000Z","dependencies_parsed_at":"2023-02-13T02:50:19.954Z","dependency_job_id":"58d7be4e-ecd1-43ff-8bb6-c21ae3edc9f4","html_url":"https://github.com/geminabox/geminabox","commit_stats":{"total_commits":505,"total_committers":100,"mean_commits":5.05,"dds":0.7386138613861386,"last_synced_commit":"de5bfab1f1916a665cd1ad9d8d2d395281327b0f"},"previous_names":[],"tags_count":69,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geminabox%2Fgeminabox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geminabox%2Fgeminabox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geminabox%2Fgeminabox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geminabox%2Fgeminabox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/geminabox","download_url":"https://codeload.github.com/geminabox/geminabox/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253748020,"owners_count":21957850,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gem","hacktoberfest","ruby","rubygems"],"created_at":"2024-08-04T08:00:51.252Z","updated_at":"2025-05-12T13:32:36.793Z","avatar_url":"https://github.com/geminabox.png","language":"Ruby","funding_links":[],"categories":["Ruby","Gem Servers","Happy Exploring 🤘"],"sub_categories":[],"readme":"[![](https://repository-images.githubusercontent.com/463074/c53c4131-3d92-42db-85b0-52f1e88c219a)](https://github.com/geminabox)\n\n# Gem in a Box – Really simple rubygem hosting\n\n[![Ruby](https://github.com/geminabox/geminabox/actions/workflows/ruby.yml/badge.svg)](https://github.com/geminabox/geminabox/actions/workflows/ruby.yml?query=branch%3Amaster)\n[![Gem Version](https://badge.fury.io/rb/geminabox.svg)](http://badge.fury.io/rb/geminabox)\n[![Code Climate](https://codeclimate.com/github/geminabox/geminabox/badges/gpa.svg)](https://codeclimate.com/github/geminabox/geminabox)\n\nGeminabox lets you host your own gems, and push new gems to it just like with rubygems.org.\nThe bundler dependencies API is supported out of the box.\nAuthentication is left up to either the web server, or the Rack stack.\nFor basic auth, try [Rack::Auth](http://www.rubydoc.info/github/rack/rack/Rack/Auth/Basic).\n\n![screen shot](http://pics.tomlea.co.uk/bbbba6/geminabox.png)\n\n## System Requirements\n\n- Ruby 2.3 through 3.1 (Ruby 2.7, 3.0, or 3.1 is highly recommended)\n- RubyGems 2.5 through 3.3 (2.5.2 or higher is highly recommended)\n\nUse RubyGems the latest version (at least 2.5.2) for as an end-user full features like [`gem yank --host`](https://github.com/rubygems/rubygems/pull/1361).\n\n## Server Setup\n\n    gem install geminabox\n\nCreate a config.ru as follows:\n\n    require \"rubygems\"\n    require \"geminabox\"\n\n    Geminabox.data = \"/var/geminabox-data\" # ... or wherever\n\n    # Use Rack::Protection to prevent XSS and CSRF vulnerability if your geminabox server is open public.\n    # Rack::Protection requires a session middleware, choose your favorite one such as Rack::Session::Memcache.\n    # This example uses Rack::Session::Pool for simplicity, but please note that:\n    # 1) Rack::Session::Pool is not available for multiprocess servers such as unicorn\n    # 2) Rack::Session::Pool causes memory leak (it does not expire stored `@pool` hash)\n    use Rack::Session::Pool, expire_after: 1000 # sec\n    use Rack::Protection\n\n    run Geminabox::Server\n\nStart your gem server with 'rackup' to run WEBrick or hook up the config.ru as you normally would ([passenger](https://www.phusionpassenger.com/), [thin](http://code.macournoyer.com/thin/), [unicorn](https://bogomips.org/unicorn/), whatever floats your boat).\n\n## RubyGems Proxy\n\nGeminabox can be configured to pull gems, it does not currently have, from rubygems.org. To enable this mode you can either:\n\nSet RUBYGEM_PROXY to true in the environment:\n\n    RUBYGEMS_PROXY=true rackup\n\nOr in config.ru (before the run command), set:\n\n    Geminabox.rubygems_proxy = true\n\nIf you want Geminabox to carry on providing gems when rubygems.org is unavailable, add this to config.ru:\n\n    Geminabox.allow_remote_failure = true\n\n## HTTP adapter\n\nGeminabox uses the HTTPClient gem to manage its connections to remote resources.\nThe relationship is managed via Geminabox::HttpClientAdapter.\n\nTo configure options of HTTPClient, pass your own HTTPClient object in config.ru as:\n\n```ruby\n# Geminabox.http_adapter = Geminabox::HttpClientAdapter.new # default\nGeminabox.http_adapter.http_client = HTTPClient.new(ENV['http_proxy']).tap do |http_client|\n  http_client.transparent_gzip_decompression = true\n  http_client.keep_alive_timeout = 32 # sec\n  http_client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE\n  http_client.send_timeout = 0\n  http_client.receive_timeout = 0\nend\n```\n\nIf you would like to use an alternative HTTP gem, create your own adapter\nand specify it in config.ru:\n\n    Geminabox.http_adapter = YourHttpAdapter.new\n\nIt is recommend (but not essential) that your adapter inherits from HttpAdapter.\nThe adapter will need to replace HttpAdapter's methods with those specific to\nthe alternative HTTP gem. It should also be able to handle HTTP proxy\nsettings.\n\nDefining your own adapter also allows you to configure Geminabox to use the\nlocal systems SSL certificates.\n\nTemplateFaradayAdapter is provided as an example of an alternative HTTPAdapter.\n\n## Hooks\n\nYou can add a hook (anything callable) which will be called when a gem is\nsuccessfully received.\n\n```ruby\nGeminabox.on_gem_received = Proc.new do |gem|\n  puts \"Gem received: #{gem.spec.name} #{gem.spec.version}\"\nend\n```\n\nTypically you might use this to push a notification to your team chat. Any\nexceptions which occur within the hook is silently ignored, so please ensure they\nare handled properly if this is not desirable.\n\nAlso, please note that this hook blocks `POST /upload` and `POST /api/v1/gems` APIs processing.\nHook authors are responsible to perform any action non-blocking/async to avoid HTTP timeout.\n\n## Client Usage\n\nSince version 0.10, Geminabox supports the standard gemcutter push API:\n\n    gem push pkg/my-awesome-gem-1.0.gem --host HOST\n\nYou can also use the gem plugin:\n\n    gem install geminabox\n\n    gem inabox pkg/my-awesome-gem-1.0.gem\n\nAnd since version 1.2.0, Geminabox supports the standard gemcutter yank API:\n\n    gem yank my-awesome-gem -v 1.0 --host HOST\n\nConfigure Gem in a box (interactive prompt to specify where to upload to):\n\n    gem inabox -c\n\nChange the host to upload to:\n\n    gem inabox -g HOST\n\nSimples!\n\n## Command Line Help\n\n    Usage: gem inabox GEM [options]\n\n      Options:\n        -c, --configure                  Configure GemInABox\n        -g, --host HOST                  Host to upload to.\n        -o, --overwrite                  Overwrite Gem.\n\n\n      Common Options:\n        -h, --help                       Get help on this command\n        -V, --[no-]verbose               Set the verbose level of output\n        -q, --quiet                      Silence commands\n            --config-file FILE           Use this config file instead of default\n            --backtrace                  Show stack backtrace on errors\n            --debug                      Turn on Ruby debugging\n\n\n      Arguments:\n        GEM       built gem to push up\n\n      Summary:\n        Push a gem up to your GemInABox\n\n      Description:\n        Push a gem up to your GemInABox\n\n## Docker\n\nUsing Gem in a Box is really simple with the Dockerfile.  Move this Dockerfile into a directory that you want to use for your server.\n\nThat directory only needs to contain:\n\n```\nconfig.ru (explained above)\nGemfile\nGemfile.lock\n```\n\nYour Gemfile only needs:\n\n```ruby\nsource 'https://rubygems.org'\n\ngem 'geminabox'\n```\n\nFrom there\n\n```\ndocker build -t geminabox .\n```\n\n```\ndocker run -d -p 9292:9292 geminabox:latest\n```\n\nYour server should now be running!\n\n\n## Running the tests\n\nRunning `rake` will run the complete test suite.\n\nThe test suite uses\n[minitest-reporters](https://github.com/minitest-reporters/minitest-reporters)\nwith the default reporter. To get more detailed test output, use `rake\nMINITEST_REPORTER=SpecReporter`. With this setting, output of the Geminabox\nserver that is started for integration tests is sent to `stdout` as well.\n\n## Licence\n\n[MIT_LICENSE](./MIT-LICENSE)\n\n## ChangeLog\n\n[CHANGELOG.md](./CHANGELOG.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeminabox%2Fgeminabox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgeminabox%2Fgeminabox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeminabox%2Fgeminabox/lists"}