How to Correctly Install Rvm in Docker

How to correctly install RVM in Docker?

Long story short:

docker -it --rm myimage /bin/bash command does not start bash as a login shell.

Explanation:

When you run $ docker -it --rm myimage /bin/bash it's invoke bash without the -l option which make bash act as if it had been invoked as a login shell, rvm initializations depends on the source-ing /path/to/.rvm/scripts/rvm or /etc/profile.d/rvm.sh and that initialization is in .bash_profile or .bashrc or any other initialization scripts.

How can I fix that?

If you won't, always have the ruby from rvm add -l option.

Here is a Dockerfile with installed ruby by rvm:

FROM Debian

ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update -q && \
apt-get install -qy procps curl ca-certificates gnupg2 build-essential --no-install-recommends && apt-get clean

RUN gpg2 --keyserver hkp://keys.gnupg.net --recv-keys D39DC0E3
RUN curl -sSL https://get.rvm.io | bash -s
RUN /bin/bash -l -c ". /etc/profile.d/rvm.sh && rvm install 2.3.3"
# The entry point here is an initialization process,
# it will be used as arguments for e.g.
# `docker run` command
ENTRYPOINT ["/bin/bash", "-l", "-c"]

Run the container:

➠ docker_templates : docker run -ti --rm rvm 'ruby -v'
ruby 2.3.3p222 (2016-11-21 revision 56859) [x86_64-linux]
➠ docker_templates : docker run -ti --rm rvm 'rvm -v'
rvm 1.29.1 (master) by Michal Papis, Piotr Kuczynski, Wayne E. Seguin [https://rvm.io/]
➠ docker_templates : docker run -ti --rm rvm bash
root@efa1bf7cec62:/# rvm -v
rvm 1.29.1 (master) by Michal Papis, Piotr Kuczynski, Wayne E. Seguin [https://rvm.io/]
root@efa1bf7cec62:/# ruby -v
ruby 2.3.3p222 (2016-11-21 revision 56859) [x86_64-linux]
root@efa1bf7cec62:/#

ubuntu container install rvm failing

The command . /etc/profile.d/rvm.sh does not persist into the next RUN layer. That shell file modifies a few things, like the PATH variable, and without it, rvm will not be found in PATH. You can source it and run rvm in the same layer.

RUN bash -c "source /etc/profile.d/rvm.sh && rvm install 1.9.3-dev"

Also, see this related answer regarding rvm in 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.

Is it a bad practice to use version managers like RVM inside docker containers?

This would be considered a bad practice or anti-pattern in docker. RVM is trying to solve a similar problem that docker is solving, but with a very different approach. RVM is designed for a host or VM with all the tools installed in one place. Docker creates an isolated environment where only the tools you need to run your single application are included.

Containers are ideally minimalistic, only containing the prerequisites needed for your application, making them more portable. Docker also uses layers and a union filesystem to reuse common base images for each image, so any copy of something like Ruby version X is only downloaded and written to disk once, ever (ignoring updates to that image).

rvm installation not working: RVM is not a function

You are not using an login shell.

The process of enabling the login flag is described here, also some details on what a login shell is can be found here.

Thus, you need to check the option "Run as login shell" in the Gnome terminal's settings. It is required to open new terminal after this setting the flag.

Sometimes it is required to set the command to /bin/bash --login.


For remote connections it is important to understand the differene between running interactive ssh session and executing single commands.

While running ssh server and then working with the server interactively you are using login shell by default and it's all fine, but for ssh server "command" you are not using login shell and it would be required to run it with ssh server 'bash -lc "command"'.

Any remote invocation can have the same problem as executing single command with ssh.



Related Topics



Leave a reply



Submit