当构buildDockerfile时,linux source命令不起作用
我有一个定义Ruby on Rails堆栈的Dockerfile。
这是Dockerfile:
FROM ubuntu:14.04 MAINTAINER example <examplen@example.com> # Update RUN apt-get update # Install Ruby and Rails dependencies RUN apt-get install -y \ ruby \ ruby-dev \ build-essential \ libxml2-dev \ libxslt1-dev \ zlib1g-dev \ libsqlite3-dev \ nodejs \ curl RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 RUN curl -sSL https://get.rvm.io | bash -s stable --rails RUN /bin/bash -c "source /usr/local/rvm/scripts/rvm" # Install Rails RUN gem install rails # Create a new Rails app under /src/my-app RUN mkdir -p /src/new-app RUN rails new /src/new-app WORKDIR /src/my-app # Default command is to run a rails server on port 3000 CMD ["rails", "server", "--binding", "0.0.0.0", "--port" ,"3000"] EXPOSE 3000
当我执行命令docker build -t anotherapp/my-rails-app .
我得到以下错误:
拆下中间容器3f8060cdc6f5
第8步:运行gem install rails
—>运行在8c1793414e63
错误:安装rails的错误:
主动支持需要Ruby版本> = 2.2.2。
命令'/ bin / sh -c gem install rails'返回一个非零的代码:1
它看起来像命令source /usr/local/rvm/scripts/rvm
在构build期间不工作。
我不确定这是为什么发生。
从docker生成器参考中 ,每个RUN命令都是独立运行的。 所以RUN source /usr/local/rvm/scripts/rvm
对下一个RUN命令没有任何影响。
尝试更改需要给定源文件的操作,如下所示
RUN /bin/bash -c "source /usr/local/rvm/scripts/rvm ; gem install rails"
这不是直接回答你的问题,而是解决问题的另一种方法。
Docker提供了一个正式的 Ruby映像 。 这是Docker Compose和Rails快速入门教程使用的图像。 正如你可以从他们的例子中看到的,你可以将你的Gemfile.lock复制到你的映像中,并运行bundle install
而不必担心RVM。
FROM ruby:2.2.0 RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs RUN mkdir /myapp WORKDIR /myapp ADD Gemfile /myapp/Gemfile ADD Gemfile.lock /myapp/Gemfile.lock RUN bundle install ADD . /myapp
通常情况下,只有一个使用特定版本的Ruby的容器在一个容器内运行,所以RVM能够pipe理多个版本的Ruby并不会有帮助。
如果你很好奇官方的图像是如何制作的, Dockerfile在Github上。
至于为什么发生这种情况。 正如其他人指出的那样, source
命令在当前shell中执行该文件。 每个RUN
指令
…将在当前图像的顶部执行新图层中的任何命令并提交结果。 生成的提交图像将用于Dockerfile中的下一步。
每个RUN
, ADD
, COPY
指令本质上都是在一个新的容器中启动一个新的shell并执行一个命令。
1 RUN /bin/bash -c "source /usr/local/rvm/scripts/rvm" 2 RUN gem install rails
可以读为
1 Start a brand new shell Execute: source /usr/local/rvm/scripts/rvm Save the state of the file system as an image Exit shell 2 Start a brand new shell Execute: gem install rails ...
当第1步完成时,shell(以及所有源于它的内容)消失。