docker-在每次 Gemfile 更新后重新构建?
docker-compose rebuild after each Gemfile update?
我先解释一下什么是有效的:
我使用 this docs. After I ran docker-compose up
my rails app will be running on http://docker-ip:port 中的 Docker 创建了一个新的 rails 应用程序。
然后在一个新的终端里当我运行一个这样的脚手架
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 -> 我的新脚手架工作。但是脚手架不需要 rails 服务器启动。
不工作:
所以现在说我需要一个设计 gem,我在本地 sublime 文本上更新我的 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
将从头开始安装所有需要的 gem。
那么我可以更新 Gemfile 而无需重新构建 docker-compose 吗?
或者我哪里错了?
首先,关于 docker exec
的解决方法。这不是修改容器状态的好方法。如果您需要 运行 一个应用程序容器实例怎么办? exec 不会进行任何更改。您必须在那里再次安装 gems,或重建映像。当您需要 运行 多个容器时,这种情况并不少见。例如,您使用 docker-compose up
到 运行 开发环境,并且在近终端中使用 docker-compose run --rm web bash
到第二个应用程序容器中的 运行 shell 并使用它来 运行 测试、迁移、生成器或使用 rails console
而无需停止由 docker-compose 启动的容器。
现在谈谈解决方案。当你 运行 docker-compose run --rm app bundle install
,你创建新的容器,安装新的 gems 到它(这个操作更新 Gemfile.lock
,你看到这个变化,因为你的项目目录是安装到容器),然后退出。由于 --rm
标志,容器被删除。在容器中所做的更改不会影响图像。
为避免在每次 gem 安装时重建图像,您可以添加一个服务来存储 gems。这是在 docs.
的基础上修改的 docker-compose.yml
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 容器。当然,您不需要为要安装新 gem 的每个容器使用 bundle exec
。所以它更容易 time-saving。
然而,这需要在初始 docker-compose build
之后额外 bundle install
,因为在创建和首次安装 /bundle_cache
到带有应用程序的容器时,它将是空的。但是在那之后你的 gems 将被存储在单独的容器中,并且这个存储将可用于每个启动的应用程序容器。
我先解释一下什么是有效的:
我使用 this docs. After I ran docker-compose up
my rails app will be running on http://docker-ip:port 中的 Docker 创建了一个新的 rails 应用程序。
然后在一个新的终端里当我运行一个这样的脚手架
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 -> 我的新脚手架工作。但是脚手架不需要 rails 服务器启动。
不工作:
所以现在说我需要一个设计 gem,我在本地 sublime 文本上更新我的 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
将从头开始安装所有需要的 gem。
那么我可以更新 Gemfile 而无需重新构建 docker-compose 吗?
或者我哪里错了?
首先,关于 docker exec
的解决方法。这不是修改容器状态的好方法。如果您需要 运行 一个应用程序容器实例怎么办? exec 不会进行任何更改。您必须在那里再次安装 gems,或重建映像。当您需要 运行 多个容器时,这种情况并不少见。例如,您使用 docker-compose up
到 运行 开发环境,并且在近终端中使用 docker-compose run --rm web bash
到第二个应用程序容器中的 运行 shell 并使用它来 运行 测试、迁移、生成器或使用 rails console
而无需停止由 docker-compose 启动的容器。
现在谈谈解决方案。当你 运行 docker-compose run --rm app bundle install
,你创建新的容器,安装新的 gems 到它(这个操作更新 Gemfile.lock
,你看到这个变化,因为你的项目目录是安装到容器),然后退出。由于 --rm
标志,容器被删除。在容器中所做的更改不会影响图像。
为避免在每次 gem 安装时重建图像,您可以添加一个服务来存储 gems。这是在 docs.
的基础上修改的docker-compose.yml
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 容器。当然,您不需要为要安装新 gem 的每个容器使用 bundle exec
。所以它更容易 time-saving。
然而,这需要在初始 docker-compose build
之后额外 bundle install
,因为在创建和首次安装 /bundle_cache
到带有应用程序的容器时,它将是空的。但是在那之后你的 gems 将被存储在单独的容器中,并且这个存储将可用于每个启动的应用程序容器。