はじめに
どうもDockerを十分理解しないまま、雰囲気に任せてサーバーを立てていた馬鹿者です
RailsとDockerでAPIを作成していたのですが、ある日rails s
でエラーが出ました。
この手のエラーはgemに原因があったりしますが、今回はDockerに原因があったので
(いや、自分に原因がある)まとめます。
今までどうやってサーバを立ち上げていたのか
まずは作業ディレクトリにあるdocker-compose.ymlに記述したコンテナを
作成&起動させるためにdocker-compose up -d
を実行します
次に、rails s
でサーバを起動させます。(←ここがポイント)
この時点で、いつもならサーバが立ち上がり、localhost:3000なんかに繋がりました
突如のrails aborted
さて、いつも通りに上記のムーブを実行したのですがエラーメッセージがでました
まとめると次の三つが解決のヒント
Bootsnap::LoadPathCache::FallbackScan
cannot load such file -- leveldb-native (LoadError)
LoadError: cannot load such file -- leveldb-native
bootsnapについてのエラーは以前にこの方法で解決したことがあったので
temp/cacheを削除してもうrails s
を実行しますが、効果なし。。。
先輩エンジニアにヘルプを投げると
「LinuxとMacのleveldbが干渉して何回か使ってるとbootsnapのエラーが出て死ぬ」
とのこと
??正直理解できませんでした。だってMacで開発してるのに、Linux?...あっ
「Dockerとローカルディレクトリの両方でRails使ってんじゃん」
原因
docker-compose.ymlでイメージの中に
command: ["bin/rails", "s", "-b", "0.0.0.0"]
を記述しており、前述のサーバの立ち上げ方法だと
Dockerもローカルディレクトリ参照しているのでleveldbが干渉してしまう。
Railsの環境がDockerとローカルディレクトリで重複してしまい
使ってるgemのnativeが変わるので壊れる
つまり
DockerのRailsのみ使用するかMacのRailsのみを動かすようにしてたら壊れないはず
(この結果bootsnapがなぜ死ぬのはわかりません。どなたかご教授ください)
解決法
おとなしく、bundleを削除し、Dockerの環境を構築し直す
自分の場合は
$ rm -rf vendor/bundle
からの
$ docker-compose down
でdockerをとめて、
$ docker-compose run web bundle exec rails db:create db:migrate
で環境構築し直し
$ docker-compose up -d db
でdbに関するイメージだけ起動したのち
$ rails s
で無事にサーバが立ちました
諸先輩方。すいませんでした
まとめ
以下の知見を得ました
・Dockerはローカルディレクトリも参照しており、干渉する可能性がある
・leveldbとbootsnapは意外な関係がある
そもそも、docker-compose.ymlの内容を少し理解していたら
こんなことにはならなかったでしょう
僕の勉強不足です