How to Install Ruby on Docker

How to install Ruby on docker?

You could start view a dockerfile starting with:

# 2016
FROM ruby:2.3.0

# 2020
# Import your ruby version
FROM ruby:2.7.1
# Install bundler gem
RUN gem install bundler
# Assign a work directory
WORKDIR /work

That would use the docker image ruby, with ruby already installed.

The 2020 version comes from "Ruby version management with docker" from Arjun Das, mentioned by ArMD in the comments.

Creating Docker with Ruby and R

You can use the stand alone version of ruby-build.
Note that you are root and not shalev inside the container:

FROM rocker/r-ver:3.6.3

RUN apt-get update -qq && \
apt-get install -y \
apt-utils apt-transport-https \
build-essential libpq-dev nodejs

RUN apt-get install -y \
git-core zlib1g-dev build-essential \
libssl-dev libreadline-dev libyaml-dev \
libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev \
libcurl4-openssl-dev software-properties-common \
libffi-dev nodejs yarn curl bzip2

RUN git clone https://github.com/rbenv/rbenv.git ~/.rbenv \
&& echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc \
&& echo 'eval "$(rbenv init -)"' >> ~/.bashrc

ENV PATH "/root/.rbenv/bin/:/root/.rbenv/shims/:$PATH"
ENV RUBY_VERSION 2.7.1

RUN git clone https://github.com/rbenv/ruby-build.git && \
PREFIX=/usr/local ./ruby-build/install.sh

RUN rbenv install $RUBY_VERSION && \
rbenv global $RUBY_VERSION && \
rbenv versions

RUN mkdir /app

Installing gems in Dockerfile without Gemfile

You can think about splitting your gemfile, think about the following files.

slow-gems

ruby File.read('.ruby-version').strip

gem 'rubocop'

gemfile

ruby File.read('.ruby-version').strip

# add the "slow" gems to the gem-bundle so we do not have to redefine them.
instance_eval File.read('slow-gems')

gem 'flay'

dockerfile

WORKDIR /app

ADD slow-gems slow-gems.lock .ruby-version /app/
RUN bundle install --gemfile=slow-gems

ADD Gemfile Gemfile.lock /app/
RUN bundle install

This also prevents you from redefining all the gems in the docker image and the gemfile. The only problem you might encounter that the version in both lock-files will drift apart. For now, I don't have a solution for that, but this can also happen while using your current method of adding them to the dockerfile.

The second bundle install will re-use the already installed gem from the slow-gems-file, this takes less than a second.

Adition:
Don't forget to use docker's built-in caching, else this will not be faster and does not help you.

Bundler 2.2.0 and Ruby 2.7.5 on Docker crashing

Building a Docker Image with an Updated Bundler Version

You're missing a couple of steps in your Dockerfile build for bundled gems. After you update Bundler, you also need to update your Gemfile.lock and possibly re-run bundle install. There are a lot of options involved, but here's my personal recommendation for your Dockerfile based on your post:

# Note: Don't lock your Bundler version unless you
# have a VERY good reason to do so. Update will
# install or update, as needed.
RUN gem update bundler --no-document \
&& gem clean bundler \
&& bundle update --bundler \
&& bundle install

The key here is that if you don't use bundle update --bundler then the Gemfile.lock will not contain the version of Bundler that you're expecting to call. Recent versions of Bundler will downgrade themselves to the version in the Gemfile.lock if necessary, so this is really the key to the whole thing.

In addition, if you continue to have problems after applying the recipe above, you may need to figure out where Bundler is actually being installed inside your container image. While Bundler (currently) doesn't run from inside your bundle, the required version still needs to be in GEM_HOME, GEM_ROOT, or GEM_PATH in order to be found when you invoke it.

As a final consideration, if you're building your gems locally or modifying your Gemfile.lock and then using an ADD or COPY command to place the Gemfile.lock or any vendored gems into your container image, you need to perform these activities outside of Docker rather than inside the Dockerfile. Based on your original post it doesn't look like you're doing that now, but it's another option to consider as you work on resolving this.



Related Topics



Leave a reply



Submit