2017-04-25 125 views
5

这是我在我的Dockerfile如何在Docker中正确安装RVM?

RUN gpg2 --keyserver hkp://keys.gnupg.net --recv-keys D39DC0E3 
RUN curl -L https://get.rvm.io | bash -s stable 
RUN /bin/bash -l -c "rvm requirements" 
RUN /bin/bash -l -c "rvm install 2.3.3" 

工作得很好,但是,当我启动容器,我看到:

$ docker -it --rm myimage /bin/bash 
/root# ruby --version 
ruby 1.9.3p484 (2013-11-22 revision 43786) [x86_64-linux] 
/root# /bin/bash -l -c "ruby --version" 
ruby 2.3.3p222 (2016-11-21 revision 56859) [x86_64-linux] 

显然,这不是我想要的。据我所知,问题是bash默认情况下不运行/etc/profile。这就是为什么Ruby不是来自RVM安装。我该如何解决这个问题?

+0

问题:码头工人,容器内为什么要使用RVM?根据我的经验,码头工人会使rvm过时。你为每个你需要的ruby版本站起来一个新的容器。可能有些东西我错过了,但我很想知道为什么你在Docker中使用rvm。 –

+0

好问题。这是一个通用Docker镜像,许多项目都使用它。每个项目必须有能力使用自己的Ruby版本,只需要说'rvm install 2.1.0',而不需要创建自己的Docker镜像。所有这些都发生在www.rultor.com项目中。 – yegor256

+0

有趣....在这种情况下,我会创建一个基础图像,其中包含您需要的所有内容,然后再选择特定的ruby版本。从那里创建额外的dockerfiles,从你的基础镜像中继承'FROM'并安装所需的特定ruby版本。没有rvm需要。当然,我大大简化了这种情况。在现实生活中可能并不那么容易:) –

回答

8

长话短说:

docker -it --rm myimage /bin/bash命令不启动bash作为登录shell。

说明:

当你运行$ docker -it --rm myimage /bin/bash它调用的bash没有-l选项,使bash行为就好像它被调用作为登录shell,rvm初始化依赖于source -ing /path/to/.rvm/scripts/rvm/etc/profile.d/rvm.sh和初始化在.bash_profile.bashrc或任何其他初始化脚本。

我该如何解决这个问题?

如果你想总是有从rvmruby添加-l选项。

这里是一个Dockerfile安装rubyrvm

FROM debian 

ARG DEBIAN_FRONTEND=noninteractive 
RUN apt-get update -q && \ 
    apt-get install -qy 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"] 

运行容器:

➠ 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 
[email protected]:/# rvm -v 
rvm 1.29.1 (master) by Michal Papis, Piotr Kuczynski, Wayne E. Seguin [https://rvm.io/] 
[email protected]:/# ruby -v 
ruby 2.3.3p222 (2016-11-21 revision 56859) [x86_64-linux] 
[email protected]:/# 
+0

你可以请你说明我是如何更改我的'Dockerfile',以便每次运行'docker/bin/bash' Ruby版本是2.3.3? – yegor256

+0

我可以想象的唯一一件事就是在'ENTRYPOINT'选项(或者'CMD',或者将'CMD'指向一个执行初始化的shell脚本)中进行初始化,就像这样''[[-s“/ path_to_rvm /.rvm/scripts/rvm“]] &&。“/path_to_rvm/.rvm/scripts/rvm”&&/bin/bash',这应该首先检查rvm脚本,第二个'source'脚本并加载'bash' shell。 _注意关于'/ path_to_rvm'_! –

+0

如果您只是将您的Dockerfile版本发布到您的答案中,将会很好,对其他人也很方便。谢谢! – yegor256