How to use S3 bucket as gem source.
Gem server solutions with their wide feature set, come in very handy for usecases like private hosting, mirroring and inter-release builds. With s3 bucket as your gem source, you get convenience of a private gem server, without the hassle of running or maintaining a host. In this guide, we cover steps required for setting up a private gem source using a s3 bucket and configuration for its use with the gem
command.
Please check s3 documentation if you would like to learn about creating a s3 buckets and their pricing.
Make sure you are running on ruby gems version that supports s3 signing. You can update your ruby gems with the following command:
$ gem update --system
Setting up repo
For a static gem source, you will need 4 additional files beside the <gemname>.gem
file:
specs.<version>.gz
latest_specs.<version>.gz
prerelease_specs.<version>.gz
quick/Marshal.<version>/<gemname>.gemspec.rz
You can generate all of them using one command: gem generate_index
.
$ mkdir ~/repo && cd ~/repo
# <gemname>.gem must exist in a directory named `gems`
$ mkdir gems && wget -P gems/ https://rubygems.org/downloads/rake-12.3.2.gem
$ gem generate_index --directory .
# replace bucket1 with name of the bucket you created
$ aws s3 sync . s3://bucket1
Use with gem command
It’s good practice to create a separate IAM user with only read rights on the S3 bucket. Use a other IAM user for pushing the gems with write rights.
You can use your s3 source using --source
flag:
$ gem install rake -v 12.3.2 --source s3://<AWS_ACCESS_KEY_ID>:<AWS_SECRET_ACCESS_KEY>@bucket1
Use .gemrc
if you would like to pre configure multiple s3 sources. It also helps avoid issues related to special characters in the secret key and allows you to specify s3 bucket region.
Add your s3 source under :sources
key. Each s3 bucket should have its own set of credentials in a hash under s3_source
key. You can use one of the providers to extract AWS credentials:
env
- AWS environment variablesinstance_profile
- AWS EC2 Instance Metadata - will only work on the actual EC2 instance
Or set AWS access id, secret and session token explicitly.
Note that you need to add
<path_to_gems_dir>/
to your s3 source uri, if your gem repo doesn’t exist at the root of the bucket. NOTE: The trailing slash.
$ cat ~/.gemrc
:sources:
- s3://bucket1/
- s3://bucket2/
- s3://bucket3/path_to_gems_dir/
- s3://bucket4/
- https://rubygems.org/
:s3_source:
:bucket1:
:provider: env
:bucket2:
:provider: instance_profile
:region: us-west-2
:bucket3:
:id: AOUEAOEU123123AOEUAO
:secret: aodnuhtdao/saeuhto+19283oaehu/asoeu+123h
:region: us-east-2
:bucket4:
:id: AOUEAOEU123123AOEUAO
:secret: aodnuhtdao/saeuhto+19283oaehu/asoeu+123h
:security_token: AQoDYXdzEJr
:region: us-west-1