一言で Doker を表すと、「コンテナ型の仮想化ソフトウェア」であると言えます。コンテナ型仮想化技術 は、従来のハイパーバイザー型仮想化技術よりも軽量でOS資源を効率的に節約できます。
また、コンテナ単位 で稼働しているアプリケーションの共有や移動もより簡易的であり、実際にこのWebアプリケーションもDockerを利用して運用しています。
volumesは簡単にいうとコンテナの外部にデータを保存できる機能です。
例えば、開発中にサンプルアカウントを5人作成します。その後、コンテナを削除すると用意したサンプルアカウントのデータが消えます。
しかし、volumesを使うことでコンテナを削除しても外部にデータが保管されているため、再度コンテナを立ち上げても同じデータを参照することができます。
このことを、データの永続化といいます。
このWebアプリの開発にもDockerを活用しています。その際に手こずったことを紹介しながら、現状の自分の理解をここに残します。
手こずったことは「volumesの更新」です。
このWebアプリの開発でvolumesに指定しているのは以下の2つです。
1
2
3
volumes:
gemdata:
mysqldata:
この2つのデータを永続化しています。
gemdataの方で手こずりました。gemdataは利用しているライブラリの情報が保管されています。
便利な点は、いちいちライブラリをインストールする手間が省ける点です。
一度インストールしたライブラリはvolumesで保管されているので、コンテナを削除してもvolumesからライブラリの情報を参照できるため、スムーズに開発を進めることができます。
手こずったのは、前述した通りvolumesの更新です。
開発中にライブラリを追加することがありました。そこで、追加したライブラリを反映するためにdocker-compose build
を行なっても
1
Could not find kaminari-1.2.2, ... in locally installed gems (Bundler::GemNotFound)
というエラーが出ました。docker-compose down
をして、やり直してもgemがインストールされませんでした。
結論として、docker-compose build
を実行しても、volumesが既に存在しているため、再構築された内容がvolumesに反映されませんでした。そのため、buildをした後にdocker-compose up
を行うと build 前のvolumesを参照して起動するのでBundler::GemNotFound
が出力されるというわけです。docker-compose build
で、既存のvolumesを上書きすることができないということになります。
そこで、行なったのがdocker-compose run コンテナ名 bundle install
です。その結果、gemのインストールが反映されてうまく実行できました。(でも、なぜか余分なコンテナが生成されてる?...)
そのため「run
でvolumesを更新」できた!!
っと勘違いしました😅
実際には、docker-compose run
にvolumesを更新する機能はありません。では、なぜうまくいったのか順番に説明します。
docker-compose run
で起きたことrun
には、新しいコンテナを生成する機能があります。そのため、docker-compose run コンテナ名 bundle install
を実行することで、全く別の新しいコンテナが生成されます。これが、余分に生成されたコンテナの正体です。
そして、run
コマンドにはすでにあるvolumesを再利用する仕様があります。そのため、すでに docker-compose.yml
ファイルで定義してあるvolumesを再利用します。すると、そのvolumesにgemのデータがインストールされます。
実行したrun
によってvolumesにgemのデータがインストールされ、そのvolumesを今まで稼働していたコンテナが参照することでBundler::GemNotFound
を解消することができました。
この一連の流れで、私はrun
でvolumesを更新できる!!と勘違いしました。
整理すると、run
で新しく別のコンテナを生成することで、volumesにgemのデータを「強引に」追加したというのが正確な捉え方だと思います。
docker-compose 'up' とか 'build' とか 'start' とかの違いを理解できていなかったのでまとめてみた
Docker Compose + Railsでイメージ内でbundle installしているはずなのにgemが無いとエラーがでる。