루비의 도커 이미지에서 두 개 이상의 Gemfile을 사용할 수없는 문제
bundler에 이미 issue로서 오르고 있지만, 일본어의 정보가 적기 때문에 정리해 둔다.
htps : // 기주 b. 코 m/분 dぇr/분 dぇr/이스에 s/6154
문제 재현 조건
ruby : 2.5.1의 이미지에서 처음으로 다음과 같이 Dockerfile과 Gemfile을 만들고 Docker 이미지를 빌드한다.
DockerfileFROM ruby:2.3
ADD Gemfile /tmp/bundle/
RUN cd /tmp/bundle && bundle install
Gemfile# frozen_string_literal: true
source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
# gem "rails"
gem "json"
$ docker build -t rb_test .
(처음부터 docker run -it ruby:2.5.1 /bin/bash
로 대화적 환경에서 동등한 작업을 하면 좋을 것 같다. 그러나 이 방법으로는 문제는 재현하지 않는다. 피할 수있는 것 같습니다.)
여기서 두 번째 Ruby 프로젝트가 있다고 해서 새로운 Gemfile을 만들어 설치해 본다.
$ docker run -it rb_test /bin/bash
컨테이너 내에 로그인할 수 있으므로 여기에서 새롭게 Gemfile을 만들어 bundle
를 실행해 본다.
$ mkdir -p ~/proj
$ cd ~/proj
$ bundle init
$ # 適当なGemfileを作って、中身に適当なgemを加える
$ echo 'gem "pry"' >> Gemfile
$ bundle
그러면 bundle 자체는 정상 종료하지만,/tmp/bundle/Gemfile에 쓰여진 gem이 인스톨 되어 버린다.
proj로 이동한 후에도/tmp/bundle/Gemfile을 계속 참조해 버리는 것 같다.
당연히 bundle exec pry
를 실행해도 필요한 gem이 없기 때문에 에러가 된다.
문제 조사
분명히 이것은 Ruby의 docker 이미지이며 bundler1.16의 경우에 발생하는 문제 인 것 같습니다.
루비의 도커의 이미지에서는 gem을 「글로벌」에 인스톨 하는 방식이 취해지고 있다.
자세한 것은 이해하고 있지 않지만, 이 사양이 bundler1.16과의 궁합이 나쁜 모양.
Dockerfile# install things globally, for great justice
# and don't create ".bundle" in all our apps
ENV GEM_HOME /usr/local/bundle
ENV BUNDLE_PATH="$GEM_HOME" \
BUNDLE_BIN="$GEM_HOME/bin" \
BUNDLE_SILENCE_ROOT_WARNING=1 \
BUNDLE_APP_CONFIG="$GEM_HOME"
2.5.1의 dockerfile은 여기
무슨 일이 일어나고 있는지 자세히 살펴보십시오.
우선 이미지를 기동한 직후, bundle 명령은 /usr/local/bin
에 인스톨 되고 있다.
그러나 일단 번들을 실행 한 후에는 다음과 같이됩니다.
$ which bundle # /usr/local/bundle/bin/bundle
/usr/local/bundle/bin/bundle
라는 파일이 만들어져 그 내용을 살펴보면 다음과 같은 설명이 있다.
/usr/local/bundle/bin/bundle def gemfile
gemfile = ENV["BUNDLE_GEMFILE"]
return gemfile if gemfile && !gemfile.empty?
File.expand_path("../../../../../tmp/bundle/Gemfile", __FILE__)
end
무려,/tmp/bundle의 Gemfile의 패스가 하드 코드 되고 있다(!!!)
이후 bundle 커멘드를 실행해도, 이 새롭게 생긴 bundle 커멘드가 참조되어 현재 디렉토리의 Gemfiel가 참조되지 않는다고 하는 함정이었다.
(이것을 알아 차릴 때까지 저것이나 이것이나 조사해 꽤 시간을 사용했다 )
회피 방법
2018년 5월 현재, 아직 github의 issue는 오픈한 채.
우선 github issue에서도 논의되고 있는 잠정적인 회피책으로서는 환경 변수로서 export BUNDLE_GEMFILE=./Gemfile
를 지정하는 방법이 있다.
통상bundle을 실행했을 때에는 현재 디렉토리에 있는 Gemfile이 참조된다. (현재 Gemfile이 없으면 상위 디렉토리를 찾으러 간다)
그러나 한 번 번들을 실행 한 후 Gemfile의 경로가 결정되는 상황이되므로 환경 변수 BUNDLE_GEMFILE을 사용하여 억지로 현재의 것을 참조하는 것으로 회피할 수 있다.
왜 bundle이 bin 아래에 bundle 명령을 스스로 만드는지 아직 파악하지 않았기 때문에, 만약 알고 있는 분이 있으면 가르쳐 주세요. bundle 명령 자체의 버전을 고정하기 위해(?)
Reference
이 문제에 관하여(루비의 도커 이미지에서 두 개 이상의 Gemfile을 사용할 수없는 문제), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/yohm/items/6b1f8daddd83343962ae
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
FROM ruby:2.3
ADD Gemfile /tmp/bundle/
RUN cd /tmp/bundle && bundle install
# frozen_string_literal: true
source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
# gem "rails"
gem "json"
$ docker build -t rb_test .
$ docker run -it rb_test /bin/bash
$ mkdir -p ~/proj
$ cd ~/proj
$ bundle init
$ # 適当なGemfileを作って、中身に適当なgemを加える
$ echo 'gem "pry"' >> Gemfile
$ bundle
분명히 이것은 Ruby의 docker 이미지이며 bundler1.16의 경우에 발생하는 문제 인 것 같습니다.
루비의 도커의 이미지에서는 gem을 「글로벌」에 인스톨 하는 방식이 취해지고 있다.
자세한 것은 이해하고 있지 않지만, 이 사양이 bundler1.16과의 궁합이 나쁜 모양.
Dockerfile
# install things globally, for great justice
# and don't create ".bundle" in all our apps
ENV GEM_HOME /usr/local/bundle
ENV BUNDLE_PATH="$GEM_HOME" \
BUNDLE_BIN="$GEM_HOME/bin" \
BUNDLE_SILENCE_ROOT_WARNING=1 \
BUNDLE_APP_CONFIG="$GEM_HOME"
2.5.1의 dockerfile은 여기
무슨 일이 일어나고 있는지 자세히 살펴보십시오.
우선 이미지를 기동한 직후, bundle 명령은
/usr/local/bin
에 인스톨 되고 있다.그러나 일단 번들을 실행 한 후에는 다음과 같이됩니다.
$ which bundle # /usr/local/bundle/bin/bundle
/usr/local/bundle/bin/bundle
라는 파일이 만들어져 그 내용을 살펴보면 다음과 같은 설명이 있다./usr/local/bundle/bin/bundle
def gemfile
gemfile = ENV["BUNDLE_GEMFILE"]
return gemfile if gemfile && !gemfile.empty?
File.expand_path("../../../../../tmp/bundle/Gemfile", __FILE__)
end
무려,/tmp/bundle의 Gemfile의 패스가 하드 코드 되고 있다(!!!)
이후 bundle 커멘드를 실행해도, 이 새롭게 생긴 bundle 커멘드가 참조되어 현재 디렉토리의 Gemfiel가 참조되지 않는다고 하는 함정이었다.
(이것을 알아 차릴 때까지 저것이나 이것이나 조사해 꽤 시간을 사용했다 )
회피 방법
2018년 5월 현재, 아직 github의 issue는 오픈한 채.
우선 github issue에서도 논의되고 있는 잠정적인 회피책으로서는 환경 변수로서 export BUNDLE_GEMFILE=./Gemfile
를 지정하는 방법이 있다.
통상bundle을 실행했을 때에는 현재 디렉토리에 있는 Gemfile이 참조된다. (현재 Gemfile이 없으면 상위 디렉토리를 찾으러 간다)
그러나 한 번 번들을 실행 한 후 Gemfile의 경로가 결정되는 상황이되므로 환경 변수 BUNDLE_GEMFILE을 사용하여 억지로 현재의 것을 참조하는 것으로 회피할 수 있다.
왜 bundle이 bin 아래에 bundle 명령을 스스로 만드는지 아직 파악하지 않았기 때문에, 만약 알고 있는 분이 있으면 가르쳐 주세요. bundle 명령 자체의 버전을 고정하기 위해(?)
Reference
이 문제에 관하여(루비의 도커 이미지에서 두 개 이상의 Gemfile을 사용할 수없는 문제), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/yohm/items/6b1f8daddd83343962ae
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(루비의 도커 이미지에서 두 개 이상의 Gemfile을 사용할 수없는 문제), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/yohm/items/6b1f8daddd83343962ae텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)