构建Dockerfile时linux源命令不起作用

bre*_*top 4 docker dockerfile

我有一个定义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
Run Code Online (Sandbox Code Playgroud)

当我执行命令时,docker build -t anotherapp/my-rails-app .我收到以下错误:

删除中间容器3f8060cdc6f5
步骤8:运行gem安装rails
--->在8c1793414e63中运行
错误:安装rails时出错:
activesupport需要Ruby版本> = 2.2.2.
命令'/ bin/sh -c gem install rails'返回非零代码:1

看起来命令source /usr/local/rvm/scripts/rvm在构建期间不起作用.

我不确定为什么会发生这种情况.

小智 9

docker builder参考中,每个RUN命令都是独立运行的.这样做RUN source /usr/local/rvm/scripts/rvm对下一个RUN命令没有任何影响.

尝试更改需要给定源文件的操作,如下所示

  RUN /bin/bash -c "source /usr/local/rvm/scripts/rvm ; gem install rails"
Run Code Online (Sandbox Code Playgroud)


R0M*_*RMY 5

这并不能直接回答您的问题,但这是解决问题的另一种方法。

Docker提供了一个正式的 Ruby映像。这是Docker Compose and 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
Run Code Online (Sandbox Code Playgroud)

通常,使用特定版本的Ruby的容器中只能运行一个Rails应用程序,因此RVM管理多个版本的Ruby的功能将无济于事。

如果您对官方图像的制作方式感到好奇,可以在Github上找到Dockerfile


至于为什么会这样。就像其他人指出的那样,sourcecommand在当前shell中执行文件。每条RUN指令

...将在当前图像顶部的新层中执行所有命令,并提交结果。生成的提交映像将用于Dockerfile中的下一步。

每个RUNADDCOPY指令基本上开始在一个新的容器的新壳和执行命令。

1 RUN /bin/bash -c "source /usr/local/rvm/scripts/rvm"
2 RUN gem install rails
Run Code Online (Sandbox Code Playgroud)

可以读为

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
  ...
Run Code Online (Sandbox Code Playgroud)

步骤1完成后,外壳程序(以及您从中获取的所有内容)都会消失。