我将解释首先工作的是什么:
我使用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
将需要很长时间才能安装从头开始所需的所有宝石。
那么我可以在不重建docker-compose的情况下更新Gemfile吗?
或我错在哪里?
答案 0 :(得分:3)
首先,关于docker exec
的解决方法。修改容器状态不是一个好方法。如果您需要再运行一个app容器实例,该怎么办? exec不会做任何更改。您必须再次安装宝石,或重建图像。当您需要运行多个容器时,这种情况并不罕见。例如,您使用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安装时重建图像,您可以添加服务来存储gem。修改后的docker-compose.yml
基于docs。{/ p>
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:
当您使用为所有应用容器存储宝石的容器时,您根本不需要重新构建图像,因为您需要添加新的宝石,直到您运行删除所有容器的docker-compose down
(&#39} ; s真的很少需要)或者直到你自己删除bundle_cache容器。当然,您不需要为要安装新宝石的每个容器使用bundle exec
。因此,它更容易,更省时。
但是,在初始bundle install
之后,这需要额外的docker-compose build
,因为在创建并首次将/bundle_cache
挂载到带有应用程序的容器时,它将为空。但之后,您的宝石将存储在单独的容器中,并且此存储将可用于每个已启动的应用程序容器。