每个Gemfile更新后docker-compose rebuild?

问题描述 投票:4回答:1

我会先解释一下有什么作用:

我使用this docs的Docker创建了一个新的rails应用程序。在我运行docker-compose up后,我的rails应用程序将在http://docker-ip:port上运行。

然后在一个新的终端,当我运行这样的脚手架

docker-compose run --rm app bundle exec rails g scaffold note title body:text

然后呢

docker-compose run --rm app bundle exec rake db:migrate

迁移到数据库。然后当我去http://docker-ip:port - >我的新脚手架工作。但是Scaffolding不需要rails服务器启动。

不工作的东西:

所以现在说我需要一个设计宝石,我在本地崇高文本上更新我的Gemfile然后运行

docker-compose run --rm app bundle install

这将按预期安装新的设计gem。但是当我跑

docker-compose run --rm app bundle exec rails g devise:install

我收到错误: Could not find bcrypt-3.1.11 in any of the sources Run bundle install to install missing gems. 所以基本上在添加设计到Gemfile后我必须再次运行docker-compose build这需要很长时间,因为bundle install将安装从头开始所需的所有宝石。

那么我可以更新Gemfile而无需再次重建docker-compose吗?

或者我错在哪里?

ruby-on-rails docker docker-compose dockerfile docker-machine
1个回答
3
投票

首先,关于docker exec的解决方法。这不是修改容器状态的好方法。如果您需要再运行一个app容器实例,该怎么办? exec不会做任何更改。您将不得不再次安装宝石,或重建图像。当您需要运行多个容器时,这种情况并不罕见。例如,您使用docker-compose up运行dev环境,并使用docker-compose run --rm web bash在near终端中运行shell在第二个应用程序容器中并使用它运行测试,迁移,生成器或使用rails console而不停止由docker-compose启动的容器。

现在谈谈解决方案。当您运行docker-compose run --rm app bundle install时,您创建新容器,在其中安装新的gem(此操作更新Gemfile.lock,您会看到此更改,因为您的项目目录已安装到容器),然后退出。由于--rm旗帜,容器被移除。容器中所做的更改不会影响图像。

为避免在每个gem安装上重建图像,您可以添加一个服务来存储gem。这是修改后的docker-compose.yml,基于来自docs的那个。

version: '3'
services:
  db:
    image: postgres
  web:
    build: .
    command: bash -c "bundle install && bundle exec rails s -p 3000 -b 0.0.0.0"
    volumes:
      - .:/myapp
      - bundle_cache:/bundle_cache
    ports:
      - "3000:3000"
    depends_on:
      - db
    environment:
      - BUNDLE_PATH=/bundle_cache
  bundle_cache:
    image: busybox
    volumes:
      - bundle_cache:/bundle_cache

volumes:
  bundle_cache:

当您使用容器为所有应用容器存储gem时,您不需要重建图像,因为根本不需要添加新的gem,直到您运行删除所有容器的docker-compose down(它确实很少需要)或直到您自己删除bundle_cache容器。当然,您不需要为要安装新宝石的每个容器使用bundle exec。所以它更容易和省时。

然而,这需要在初始bundle install之后额外的docker-compose build,因为在创建和首次将/bundle_cache安装到带有应用的容器时它将是空的。但之后,您的宝石将存储在单独的容器中,并且此存储将可用于每个已启动的应用程序容器。

© www.soinside.com 2019 - 2024. All rights reserved.