Ruby on rails 在Dockerfile中安装gems而不使用Gemfile

Ruby on rails 在Dockerfile中安装gems而不使用Gemfile,ruby-on-rails,ruby,docker,bundle,bundler,Ruby On Rails,Ruby,Docker,Bundle,Bundler,我的团队用Dockerfile托管Rails应用程序。我们有一些缓慢的宝石,它们确实减慢了我们的构建速度。(我在看你grpc你可以使用选项包install--deployment或--path来指定一个文件夹,在那里你可以安装gems(仅为此目的构建一个容器,然后在docker外部复制该文件夹)。然后将此目录映射为容器中的卷,在映射完成后运行bundle install…或者简单地复制文件夹: 带有--path=vendor/cache的命令生成一个bundle配置,如下所示: --- BUND

我的团队用Dockerfile托管Rails应用程序。我们有一些缓慢的宝石,它们确实减慢了我们的构建速度。(我在看你
grpc
你可以使用选项包install--deployment或--path来指定一个文件夹,在那里你可以安装gems(仅为此目的构建一个容器,然后在docker外部复制该文件夹)。然后将此目录映射为容器中的卷,在映射完成后运行bundle install…或者简单地复制文件夹:

带有--path=vendor/cache的命令生成一个bundle配置,如下所示:

---
BUNDLE_DEPLOYMENT: "true"
BUNDLE_PATH: "vendor/cache"
只要编译的扩展gems版本在Gemfile上没有更改,就不应该再次安装它们

为了不将供应商/缓存文件夹提交到源文件,您可以将其托管在某个位置,并让开发人员下载。我认为您可以将此文件夹放在何处,以及如何将其复制到映像中,这是一个相当开放的问题,我需要有关您的设置的更多信息来推荐。您的应用程序具体部署在哪里生产

例如:

带有本机扩展的AWS lambda gems存在一个问题-您可以在操作系统中安装它们,但它们与lambda环境不兼容

制作gem捆绑包的方法是执行以下操作:

1-使用容器安装带有本机扩展的gems,安装方式与lambda兼容:

docker run --rm -v "$PWD":/var/task lambci/lambda:build-ruby2.7 bundle install --deployment
2-然后,在另一个容器上,将gem映射为卷或复制它们,然后运行应用程序

docker run --rm --env-file=.env -v $PWD:/var/task:ro,delegated lambci/lambda:ruby2.7 send.lambda_handler
我建议您为您的应用程序执行类似的操作—使用一个映像构建平台gems,然后使用另一个映像运行应用程序,并将这些gems传递给它。只要这两个映像是相同的操作系统,gems将是兼容的。


与此类似的设置已在非docker部署管道上为我的团队工作,在推送新版本和安装bundler以从中获取gems之前,我们将gems预安装到文件夹中。

您可以考虑拆分gemfile,考虑以下文件

慢宝石

ruby File.read('.ruby version').strip
宝石“rubocop”
gemfile

WORKDIR /app

ADD slow-gems slow-gems.lock .ruby-version /app/
RUN bundle install --gemfile=slow-gems

ADD Gemfile Gemfile.lock /app/
RUN bundle install
ruby File.read('.ruby version').strip
#将“慢”宝石添加到宝石包中,这样我们就不必重新定义它们。
实例_eval File.read('slow-gems'))
宝石“剥皮”
dockerfile

WORKDIR /app

ADD slow-gems slow-gems.lock .ruby-version /app/
RUN bundle install --gemfile=slow-gems

ADD Gemfile Gemfile.lock /app/
RUN bundle install
这也会阻止您重新定义docker映像和gemfile中的所有Gem。您可能会遇到的唯一问题是两个锁定文件中的版本会漂移。目前,我没有解决方案,但在使用当前将它们添加到docker文件的方法时,也会发生这种情况

第二个
捆绑安装
将重新使用
慢速gems
-文件中已安装的gem,这需要不到一秒钟的时间

声明: 别忘了使用docker的内置缓存,否则这不会更快,也不会对您有所帮助。

问题:

所以,让我们先来理解这个问题。每当你试图加速你的应用程序时,都会花费很多时间。我想我非常理解你的问题

  • 从互联网下载创业板
  • 安装和启动应用程序
  • 可能的解决方案:

    这是docker文件的一个性能。我们有两个产生问题的区域和两种不同的解决方案

    解决方案:

    • 在本地下载gem文件并将其放入文件夹中,然后在dockerfile中将这些gem文件复制到容器中,然后安装

    • 为您的应用程序创建基础映像。从
      Ruby
      /您喜欢的任何其他文件创建基础映像,并使用上述方法安装
      gems

    • 从本地文件夹复制
      gems
      ,然后粘贴
      容器中
    • 使用
      RUN
      命令安装gems。随您的便
    这将是一个一次性过程。通过此过程,您可以安装已包含耗时gems的基础映像。现在,在应用程序内部
    dockerfile
    (它负责启动应用程序),您只需要使用自己创建的基本映像,而不是
    Ruby
    Linux
    中的
    Docker-Hub

    我们将了解如何构建您自己的基本预配置映像。
    让我们一步一步来看看。

    让我们关注一下GitHub回购协议:

    文件夹结构(这将有助于理解本文)

    • 应用程序/dockerfile
    • gems/下载并放置本地gems
    • dockerfile

    • 创建基础映像并在docker容器内安装本地gems。
    dockerfile

    使用以下命令从此dockerfile生成映像

    docker build--rm-f“dockerfile”-t ruby-gem-base-image:latest.“

    • 第1步: 我将基本映像用作ruby,如果您使用Linux,您可以选择任何您想要的,然后在下一步您需要安装
      ruby

    • 步骤2:在容器中创建文件夹名gems

    • 第3步和第4步:将需要安装在容器内的Gems从本地目录复制到
      docker
      容器内的目录
    • 第5步和第6步:将工作目录更改为gems,因为我们希望在该目录中安装gems place,所以下一个命令是
      gem install--force--local*.gem
      ,它有助于在本地目录中安装gems
    有了这个,我们解决了50%的时间消耗。现在docker将永远不会每次从互联网上下载宝石,也不会安装
    
        FROM ruby:latest
        RUN mkdir -p /gems 
        COPY /gems/grpc-1.28.0-universal-darwin.gem /gems/grpc-1.28.0-universal-darwin.gem
        COPY /gems/sassc-2.2.1.gem /gems/sassc-2.2.1.gem
        WORKDIR /gems
        RUN gem install --force --local *.gem
    
    FROM ruby-gem-base-image:latest
    CMD ["gem", "list"]