Docker&Rails環境で、gemを永続化させる


本記事について(お断り)

この記事は、しがないプログラミング初心者がお勉強よろしくプログラミング・技術に触れるべく、行ったことの備忘録として書き綴ったものです。ご了承ください。
ご指摘は甘んじて受け入れます🙇‍♂️

起こったこと

とあるプロダクトでおもむろにdocker-compose upしてたら、

...
web_1  | Bundler::GemNotFound: Could not find gem 'rspec-rails' in any of the gem sources listed in your Gemfile.
...
myapp_web_1 exited with code 1

と怒って勝手に出て行ってしまった。
おかしい、確かにインストールしたはずのgemがないとは、、、

一度落として、再度docker-compose buildすると問題なく動いた。
まあこれでもいいんだけど、毎回ビルドしてコンテナ起動するのは面倒だと思う。

調べてみると、volumeの永続化を行うことで、こうした問題が解消されるとのこと。

docker-compose.ymlの修正

現在のファイルの中身。

docker-compose.yml
ersion: '3'
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=password
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db

これを書き加える

docker-compose.yml
ersion: '3'
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=password
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
      - gem_data:/usr/local/bundle # <= ココと
    ports:
      - "3000:3000"
    depends_on:
      - db
volumes:
  gem_data: # <= ココ。

パスは、コンテナの中に入って確認できます。

$ docker-compose exec web bash
$ gem environment
RubyGems Environment:
  - RUBYGEMS VERSION: 3.0.3
  - RUBY VERSION: 2.6.5 (2019-10-01 patchlevel 114) [x86_64-linux]
  - INSTALLATION DIRECTORY: /usr/local/bundle
  ...(略)

これでgemを永続化する環境を構築できたことになります。
試しに、gemを追加、

Gemfile
+ gem 'rails-erd'

その後、bundle installしてみます。

$ docker-compose exec web bundle install

そして、一度コンテナを削除した後に再度起動してみます。

$ docker-compose down
$ docker-compose up

問題なくコンテナを起動できました!

コンテナ削除前にインストールしたgemもちゃんと入っています。

$ docker-compose exec web bundle list |grep 'rails-erd'
  * rails-erd (1.6.0)

参考

今回の作業にあたり、以下のページを参考にさせていただきました。とても勉強になりました。ありがとうございます🙇‍♂️

https://nishinatoshiharu.com/datavolume-for-gem/