我看到bundle install
和yarn install
通常在Dockerfile中完成为:
RUN bundle install && yarn install
这意味着如果我修改Gemfile或yarn.lock,则需要再次重新构建映像。我知道这里有层缓存,并且docker build将不会重建除bundle install && yarn install层之外的其他层。但这意味着我必须做docker-compose up -d --build
但是我想知道是否可以将这些命令放在docker-compose的输入脚本中,或者放入以下命令中:
command: bundle install && yarn install && rails s
我相信,以这种方式,每执行docker-compose up -d
时,bundle install
和yarn install
都将被执行而不必构建映像。
除了不必在--build
中附加docker-compose up
之外,不确定它是否比Dockerfile中的常规捆绑包安装有任何优势。请纠正,如果我这样做,即使对Gemfile或Yarn文件没有任何更改,也将执行捆绑安装和yarn安装。我想这是不好的一面。
如果这不是理想的选择,请纠正我。
docker世界的新手。
答案 0 :(得分:1)
这个问题是基于意见的。正如您已经发现的那样,通常的做法是在映像构建过程中而不是映像运行过程中安装依赖项(捆绑,纱线,其他)。
基本原理是您run
比build
的访问次数多,并且希望运行操作能够快速启动。
与在构建阶段执行apt install...
或yum install...
的方式相同,通常在构建阶段也应执行bundle install
。
也就是说,如果您认为bundle install
作为入口点的一部分是您的选择,那么这就是您的选择。我怀疑执行此操作后,您会发现它不常见是有原因的。
关于docker层的另一条注释:如果Gemfile发生变化,不仅引用它的层将发生变化,所有后续层也将发生变化。因此,通常将依赖项清单(Gemfile.*
)的副本与应用程序的副本分开,如下所示:
# Pre-install gems
COPY Gemfile* ./
RUN gem install bundler && \
bundle install --jobs=3 --retry=3
# Copy the rest of the app
COPY . .
这样,如果您的应用文件发生了变化,但相关性没有发生变化,构建速度将会更快。
答案 1 :(得分:1)
这会浪费几分钟的时间,并且每次启动应用程序时都会占用网络带宽。当您进行本地开发时,等同于每次运行该应用程序时都要执行此操作:
rm -rf vendor node_modules
bundle install # from scratch
yarn install # from scratch
bundle exec rails s
Docker的核心部分是重建映像(就像Go,Java,Typescript,等这样的语言具有“构建”阶段)。通常不建议尝试避免图像重建。有了编写良好的Dockerfile,尤其是对于解释型语言,运行docker build
应该非常有效。
一个重要的技巧是分别复制指定依赖项的文件和应用程序的其余部分。一旦Dockerfile COPY
指令遇到一个已更改的文件,它将为应用程序的其余部分禁用层缓存。由于依存关系很少发生变化,因此如果依存关系文件未更改,则先复制依存关系文件,然后安装依存关系,然后复制应用程序的序列可以直接跳到最后一步。
COPY Gemfile Gemfile.lock ./
RUN bundle install
COPY package.json yarn.lock ./
RUN yarn install
COPY . ./
(确保在vendor
文件中包括Bundler node_modules
目录和.dockerignore
目录,因此最后的COPY
步骤不会覆盖以前安装的内容。 )