これは備忘録です(きりり)
やりたいことと状況
- 社内rubygemを作った!
- コンテナ化してない
rails new
したrailsアプリでは動作確認済み - テストも書いたけど社内gemなので社のrailsアプリに入れて動作確認したい
- それらは全部コンテナ化されている
何に困っていたか
- コンテナ化してないrailsアプリと同じ要領でGemfileでpath指定したら以下のように「そんなものはない」と言われて失敗する
# Gemfile gem 'mygem', path: '/path/to/mygem'
$ docker-compose up -> The path '/path/to/mygem' does not exist. -> railsコンテナ起動しない
docker起動後にGemfile追記してbundle install
しても同様のエラーメッセージが出ます。(まあ、それはそう)
やったこと
1. docker-compose.ymlでgemのあるディレクトリをvolumesでマウント
# docker-compose.yml services: rails: (略) volumes: - /path/to/mygem:/lib/mygem
2. この状態でコンテナを起動
$ docker-compose up
3. railsのコンテナの中を確認
コマンドで確認したり
$docker inspect rails { "Type": "bind", "Source": "/path/to/mygem", "Destination": "/lib/mygem", "Mode": "rw", "RW": true, "Propagation": "rprivate" },
コンテナに入って確認したり。
$ docker exec -it rails bash # ls /lib/mygem -> mygemの中身がある
4. gemを追加
Gemfileにgemを追加してbundle installしたりdocker-composeを立ち上げ直したり。
# Gemfile gem 'mygem', path: '/lib/mygem' # コンテナ側のパス
できたけど良くなかったやり方
良くない方法
- docker-compose.ymlでgemのあるディレクトリをvolumesで指定(上と一緒)
- コンテナで
gem install mygem-1.0.0.gem
して追加
良くない理由
Gemfileで管理してないgemができてしまう
Gemfileにないということはbundlerの管轄の外になってしまう(ということは
Bundler is an exit from dependency hell
の恩恵も受けれられない)
これを調べていてわかったこと
- docker-compose fileでは
volumes
でホストのパスを指定しマウントできるが、DockerfileのVOLUMEではホストのパスを指定できないこと。Dockerfile reference | Docker Documentationによると、ホストのディレクトリはホストに依存するのでdocker run
コマンドの実行時にhost-dir
でディレクトリを宣言するようにとのことです。これはDockerfileを共有することで同じ環境を複数の開発者で共有するというDockerの良さを殺さないためだそうです。こちらのブログも参考にしました。
感想
最初自分ではマウント後gem install
してしまっていて「これでいいのかなー(もやもや)」とした状態でした。
よく考えたらその時点でコンテナ側のpathを指定したら良かったのに、「これ以上何もわからん。。。」って冷静じゃなかった気がします。
冷静になれなかった理由は”マウントしてるって言うことはどういうことか”とか"Gemfileのpath指定はどの世界の話か"っていうのをちゃんとわかってなかったり、そこを思考停止状態で日頃操作しているからかなって思いました。
Twitterで助言くださった@t_tonchimさん@udzuraさん、調べてわからんことを解説してくれた@naoty_kありがとうございました!