🐳

docker-compose.ymlのvolumesについて

2024/05/27に公開

Railsのアプリケーションを開発中、docker-compose.ymlの設定が原因で目的のページに遷移されない問題が発生しました。この記事ではdocker-compose.ymlのvolumesの目的について、私が体験したことに関連づけて解説していきます。

1:期待していた結果
まず、期待していた結果は[http://localhost:3000/]へアクセスすると実装した内容のトップページが表示されることでした。

実装していた内容は以下の通りです。

routes.rbにてルートにアクセスした際にStaticPagesControllerのtopアクションが実行されるようにする

Rails.application.routes.draw do
  root 'static_pages#top'
end

コントローラにはtopアクションを定義する

class StaticPagesController < ApplicationController
  def top; end
end

viewsではtop.html.erbとapplicaation.html.erb(layoutファイル)を以下のように設定する
※layoutファイルは通常app/views/layouts配下に配置されており、何も指定がない場合は、application.html.erbというファイルが選択されるようになっている。

top.html.erb

<div class='top-wrapper'>
  <div class='top-inner-text'>
    <h1>BOARD APP</h1>
  </div>
</div>

application.html.erb

<!DOCTYPE html>
<html>
  <head>
    <title>BOARD APP</title>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag "application" %>
    <%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %>
  </head>

  <body>
  <%= render 'shared/header' %>
    <%= yield %>
  <%= render 'shared/footer' %>
  </body>
</html>

通常、ここまで実装していればルートにアクセスした時に何かしら画面が表示されるはずです。しかし、画面に表示されたのはRailsのwelcomeページでした...

2: docker-compose.ymlのvolumes設定が原因
何が原因なのだろうと模索した結果、docker-compose.ymlのvolumesの設定がおかしいことが判明しました。

正しい設定は

web:
    ~省略~
    volumes:
      - .:/v3_basic_rails_basic
      - bundle_data:/usr/local/bundle:cached
      - node_modules:/app/node_modules

であるべきだったのですが、私のコードは以下のようになっていました。

web:
    ~省略~
    volumes:
      - .:/v3_basic_rails_basic
      - bundle_data:/usr/local/bundle:cached
      - node_modules:/v3_basic_rails_basic

node_modulesのマウント先が/app/node_modulesではなく、
/v3_basic_rails_basicになっていたのです。
とりあえず、マウント先を変更することで問題は解決したのですが、docker-compose.ymlのvolumesについて全く理解できていなかったのでこれを機にまとめてみようと思います。

3: volumesとは何か?
そもそも、docker-compose.ymlとは何かについてですが、これはDocker Composeの設定ファイルでみなさんはよく「Docker compose 〇〇」というコマンドを実行すると思いますが、Docker Composeを実行するにはdocker-compose.ymlで各種設定を行わなければいけません。
参照: https://qiita.com/gon0821/items/77369def082745d19c38

今回はdocker-compose.ymlのサービス名がwebのvolumesにいて設定が間違っていたことから問題が発生しました。

ここで本題に入りますが、volumesとはデータをコンテナの外に保存するための設定項目であり、ホストマシンにもデータを共有することでデータの永続性を可能にします。つまり、これはvolumesを設定していないと、コンテナが削除された時にそのコンテナ内にあった全てのデータが消えてしまうのです。

volumesはホスト側のディレクトリとコンテナ内のディレクトリを結びつける(=マウントする)ために使われ、ホスト上でコードの変更を行うと、その変更がリアルタイムでコンテナ内に反映されるようになります。

そこで、改めて今回のvolumesの設定について振り返ってみます。

web:
    ~省略~
    volumes:
      - .:/v3_basic_rails_basic
      - bundle_data:/usr/local/bundle:cached
      - node_modules:/app/node_modules

①.:/v3_basic_rails_basic
.は現在のホストマシンのディレクトリを指しています。これはホストマシンのディレクトリの内容がコンテナ内の/v3_basic_rails_basicディレクトリに結びつけるように設定されています。

②bundle_data:/usr/local/bundle:cachedは省略します。

③node_modules:/app/node_modules
node_modulesは名前付きボリュームです。これはDockerが管理するボリュームでコンテナ内の/app/node_modulesディレクトリに結びつけます。

今回の問題は、node_modulesのマウント先が/app/node_moduesではなく、/v3_basic_rails_basicとしてしまったことにより期待のページに遷移されませんでした。
しかし、現段階では問題となる部分はわかっても原因はまだ分かっていません。もし、マウント先が/app/node_moduesであるべき理由を知っている方がいらっしゃいましたら教えていただけると嬉しいです。

*駆け出しのため文章が分かりづらいところや説明不足のところがあるかと思います。もし、間違っている部分などがございましたらご意見いただけますと幸いです。

Discussion