构建Dockerfile

时间:2016-10-14 13:47:53

标签: 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

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

  

拆卸中间容器3f8060cdc6f5
  第8步:运行宝石安装导轨
   ---&GT;在8c1793414e63中运行
  错误:安装导轨时出错:
          activesupport需要Ruby版本&gt; = 2.2.2   命令&#39; / bin / sh -c gem install rails&#39;返回非零代码:1

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

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

2 个答案:

答案 0 :(得分:8)

docker builder reference开始,每个RUN命令都是独立运行的。所以做RUN source /usr/local/rvm/scripts/rvm对下一个RUN命令没有任何影响。

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

  RUN /bin/bash -c "source /usr/local/rvm/scripts/rvm ; gem install rails"

答案 1 :(得分:3)

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

Docker提供official Ruby image。这是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

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

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

至于为什么会这样。正如其他人指出的那样,source命令在当前shell中执行该文件。每个RUN指令

  

...将在当前图像之上的新图层中执行任何命令并提交结果。生成的已提交映像将用于Dockerfile中的下一步。

每个RUNADDCOPY指令实质上在新容器中启动一个新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(以及你所有的东西)消失了。