Я использую Slack для ruby gem (slack-ruby-client
), и часть его предварительных требований - установить faye-websocket
gem.
В моем Gemfile у меня есть следующее:
# Slack-ruby-client
gem 'slack-ruby-client'
gem 'eventmachine'
gem 'websocket-driver'
gem 'faye-websocket'
gem 'rails_best_practices'
Однако моему контейнеру Ruby кажется, что драгоценный камень websocket-driver
не нравится. Например, когда запускается docker-compose up
, контейнер запускает файл entrypoint.sh
, который просто выполняет bundle install
. После этого он пытается выполнить rails s --binding 0.0.0.0
. Это дает сбой, потому что не удается загрузить websocket/driver
Gem, как показано ниже:
sidekiq_1 | LoadError: cannot load such file -- websocket/driver
sidekiq_1 | /usr/local/bundle/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require'
sidekiq_1 | /usr/local/bundle/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `block in require_with_bootsnap_lfi'
sidekiq_1 | /usr/local/bundle/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/loaded_features_index.rb:89:in `register'
sidekiq_1 | /usr/local/bundle/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require_with_bootsnap_lfi'
sidekiq_1 | /usr/local/bundle/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:41:in `rescue in require'
sidekiq_1 | /usr/local/bundle/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:27:in `require'
sidekiq_1 | /usr/local/bundle/gems/zeitwerk-2.3.0/lib/zeitwerk/kernel.rb:23:in `require'
Если я получаю оболочку внутри контейнера, выполнив следующую команду:
docker exec -ti sidekiq_app_1 /bin/sh
Gem устанавливает просто отлично работает gem install websocket-drivr
, как показано ниже:
/myapp # gem install websocket-driver
Building native extensions. This could take a while...
Successfully installed websocket-driver-0.7.2
1 gem installed
Но если я открываю консоль ruby и пытаюсь действительно потребовать ее, это дает мне ошибку, как показано ниже:
/myapp # irb
irb(main):001:0> require 'websocket-driver'
Traceback (most recent call last):
4: from /usr/local/bin/irb:11:in `<main>'
3: from (irb):1
2: from /usr/local/lib/ruby/site_ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'
1: from /usr/local/lib/ruby/site_ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'
LoadError (cannot load such file -- websocket-driver)
irb(main):002:0> exit
myuser@ubuntu ~/Documents/app dev ● docker exec -ti sidekiq_app_1 rails c
Running via Spring preloader in process 241
Loading development environment (Rails 5.2.4)
irb(main):001:0> require 'websocket-driver'
require 'websocket-driver'
Traceback (most recent call last):
1: from (irb):1
LoadError (cannot load such file -- websocket-driver)
irb(main):002:0>
Если я запустил gem list | grep -i websocket
в контейнере, я получу следующий результат:
/myapp # gem list | grep -i websocket-driver
websocket-driver (0.7.2)
Из консоли irb
я могу успешно require 'websocket/driver'
без проблем, но если я запустил то же самое из приглашения rails c
, он вернет false
:
/myapp # irb
irb(main):001:0> require 'websocket/driver'
=> true
irb(main):002:0> exit
/myapp # rails c
Running via Spring preloader in process 376
Loading development environment (Rails 5.2.4)
irb(main):001:0> require 'websocket/driver'
require 'websocket/driver'
=> false
irb(main):002:0> quit
quit
/myapp #
Dockerfile:
FROM ruby:2.5.1-alpine
ENV BUNDLER_VERSION=2.0.2
RUN apk add --update --no-cache \
binutils-gold \
build-base \
curl \
file \
g++ \
gcc \
git \
less \
libstdc++ \
libffi-dev \
libc-dev \
linux-headers \
libxml2-dev \
libxslt-dev \
libgcrypt-dev \
make \
netcat-openbsd \
nodejs \
openssl \
pkgconfig \
postgresql-dev \
python \
tzdata \
yarn
RUN gem install bundler -v 2.0.2
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle config build.nokogiri --use-system-libraries
RUN bundle check || bundle install
COPY . /myapp
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 80
CMD ["rails", "server", "-b", "0.0.0.0", "-p", "80"]
точка входа. sh файл:
#!/bin/sh
bundle install
rake db:migrate
rake db:seed
npm install
set -e
rm -f /myapp/tmp/pids/server.pid
exec "$@"
docker -compose.yml файл:
version: "3.4"
services:
app:
build:
context: .
dockerfile: Dockerfile
depends_on:
- database
- redis
ports:
- "80:80"
volumes:
- .:/myapp
- gem_cache:/usr/local/bundle/gems
- node_modules:/app/node_modules
env_file: .env
database:
image: postgres:12.1
volumes:
- db_data:/var/lib/postgresql/data
env_file: .env
redis:
image: redis:5.0.7
env_file: .env
sidekiq:
build:
context: .
dockerfile: Dockerfile.sidekiq
depends_on:
- app
- database
- redis
volumes:
- .:/myapp
- gem_cache:/usr/local/bundle/gems
- node_modules:/app/node_modules
env_file: .env
volumes:
gem_cache:
db_data:
node_modules:
Почему это могло произойти, если он просто успешно установил драгоценный камень?