为什么我必须在容器中使用bash -l -c?

时间:2014-02-20 00:18:46

标签: linux bash shell docker

我使用以下Dockerfile创建了一个docker容器(截断):

FROM ubuntu:12.04
# curl enables downloading of other things
RUN apt-get install curl -y
# download and install rvm...
RUN \curl -L https://get.rvm.io | bash -s stable
# ... so that we can install ruby
RUN /bin/bash -l -c "rvm requirements"

等等。

这一切都有效,但我遇到的问题是如何/在何处安装软件包。

如果我只是使用docker run [...] rvm运行rvm,我会“无法找到rvm”,但如果我运行docker run [...] /bin/bash -l -c "rvm"则可行。 (我在网上找到了“-l -c”选项,但不知道他们做了什么,也找不到我正在做的令人满意的解释!)

这不是一个码头问题 - 这是一个bash / * nix问题 - 我认为有关于如何/在哪里安装内容的东西,可能与在root下运行安装有关?

只是要清楚 - 我希望能够运行我直接从CLI安装的东西。

编辑1

使用rvm安装Ruby是推荐的方法,但是如果你想在非交互式非登录shell中运行(即在docker容器中),这只会导致路径和环境变量和登录过多的麻烦脚本没有运行。

鉴于我正在使用它运行一个docker容器,根据定义它是孤立的,并且可以恢复(只是构建另一个),我真的不关心切换版本,或者隔离包,所以我决定从包repo(http://brightbox.com/docs/ruby/ubuntu/)安装Ruby。这只是“有效”。

它可能不适合你 - 我只是为了获得Foreman gem而安装Ruby,因为我通过Procfile运行应用程序,所以我不是对细节感到困惑,我只是需要它才能工作。如果你正在构建一个Ruby应用程序,我不会听从我的建议。

我的Dockerfile在这里,FWIW,https://index.docker.io/u/yunojuno/dev/

1 个答案:

答案 0 :(得分:28)

来自bash(1)

  • -l使bash行为就好像它已被作为登录shell调用一样
  • -c如果存在-c选项,则从字符串中读取命令。

您正在运行传递给-c参数的命令。 -l使其成为登录shell,因此bash首先读取/etc/profile,它可能具有rvm的路径,这是使其工作的原因。

FWIW,这是我在docker容器中安装rvm的方法。

# Install some dependencies
RUN apt-get -y -q install curl rubygems

# Install rvm
RUN curl -L https://get.rvm.io | bash -s stable

# Install package dependencies
RUN /usr/local/rvm/bin/rvm requirements

# Install ruby
RUN /usr/local/rvm/bin/rvm install ruby-2.0.0

# create first wrapper scripts
RUN /usr/local/rvm/bin/rvm wrapper ruby-2.0.0 myapp rake rails gem