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
Command for Displaying a Gem's Dependencies
Activerecord Connection Warning. (Database Connections Will Not Be Closed Automatically)
Simplest Way to Send Raw Byte-Arrays Using Ruby's Tcpsocket-Class
How to Set a Hook to Run Code at the End of a Ruby Class Definition
How to Set a Variable from a Helper Method for Inclusion in a SASS SCSS Stylesheet
Ruby on Rails Source Code Security/Obfuscation
"Encoding::Invalidbytesequenceerror" Error Occurs in Rails 3.1.0
Getting Google File Picker to Work with Drive.File Scope
Why Does .All? Return True on an Empty Array
Using Bsearch to Find Index for Inserting New Element into Sorted Array
Does Ruby 1.9.2 Have an Is_A? Function
In Ruby, How to Get Instance Variables in a Hash Instead of an Array
Twitter Bootstrap Displays Button with Greyed Text