Rails 捆绑"Can't find GEM in any of the sources"仅在 Docker 容器中



我在Docker容器中使用Rails,偶尔会遇到这个我不知道如何解决的问题。当向Gemfile添加新的gem时,在重建Docker Image+Container时,构建将失败,并出现常见的bundler错误Could not find [GEM_NAME] in any of the sources; Run 'bundle install' to install missing gems。当我尝试在Docker中构建映像时,如果我在本地机器上运行常规bundle install,Gemfile就会正确安装,并且一切正常。

我有一个相当标准的Dockerfile&docker-compose文件。

Dockerfile:

FROM ruby:2.6.3
ARG PG_MAJOR
ARG BUNDLER_VERSION
ARG UID
ARG MODE
# Add POSTGRESQL to the source list using the right version
RUN curl -sSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - 
&& echo 'deb http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main' $PG_MAJOR > /etc/apt/sources.list.d/pgdg.list
ENV RAILS_ENV $MODE
RUN apt-get update -qq && apt-get install -y postgresql-client-$PG_MAJOR vim
RUN apt-get -y install sudo
RUN mkdir /usr/src/app
WORKDIR /usr/src/app
COPY Gemfile /usr/src/app/Gemfile
COPY Gemfile.lock /usr/src/app/Gemfile.lock
ENV BUNDLER_VERSION $BUNDLER_VERSION
RUN gem install bundler:$BUNDLER_VERSION
RUN bundle install
COPY . /usr/src/app
# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]

docker-compose.yml:

version: '3'
services:
backend:
build:
dockerfile: Dockerfile
args:
UID: ${UID:-1001}
BUNDLER_VERSION: 2.0.2
PG_MAJOR: 10
mode: development
tty: true
stdin_open: true
volumes:
- ./[REDACTED]:/usr/src/app
- gem_data_api:/usr/local/bundle:cached
ports:
- "3000:3000"
user: root

我试过docker system prune -adocker builder prune -a、重新安装Docker、连续多次重建、重新启动机器等等,都没有用。奇怪的是,我决定添加的每一颗新宝石都不会出现这种情况,只是针对一些特定的宝石。例如,我在尝试将gem 'sendgrid-ruby'添加到我的Gemfile时再次遇到这个问题。这是供参考的gem的repo,我用sendgrid-ruby得到的具体错误是Could not find ruby_http_client-3.5.1 in any of the sources。我尝试在Gemfile中指定ruby_http_client,还尝试将ssh插入Docker容器并运行gem install ruby_http_client,但我也遇到了同样的错误。

这里可能发生了什么?

您正在容器的/usr/local/bundle目录上装载一个命名卷。命名卷将从映像中填充,但仅在第一次运行容器时填充。之后,命名卷的旧内容将优先于映像的内容:以这种方式使用卷将导致Docker完全忽略您在Gemfile中所做的任何更改。

您应该能够从docker-compose.yml文件中删除volumes:行。我不清楚将已安装的gem保存在命名卷中会给您带来什么好处。

最新更新