名前付きボリュームを認識した話

Docker, Docker Composeの設定には(にも?)まだまだ疎いところがある。

今回は名前付きボリューム設定について認識できたので、その内容を記録する。

他の設定、コメントなども含まれるが https://github.com/nibuno/emoemo/pull/14/files から実際のコードを閲覧できる。

設定がうまく出来ずに困っていた

元々はcompose.yamlに対して以下のような設定をしていた。

services:
  db:
    image: postgres:16.3
    volumes:
      - ./data/db:/var/lib/postgresql/data
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_DB=postgres
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/emoemo
    ports:
      - "8000:8000"
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_DB=postgres
    depends_on:
      - db

そこから、.envファイルを追加し、内容と合わせようとservices側のenvironment を以下のように変更した。

services:
  db:
    image: postgres:16.3
    volumes:
      - ./data/db:/var/lib/postgresql/data
    environment:
      - POSTGRES_USER=emoemo_dev_user
      - POSTGRES_PASSWORD=emoemo_dev_pass
      - POSTGRES_DB=emoemo_dev

.envファイルの関連する設定値は以下の状態。

SQL_DATABASE=emoemo_dev
SQL_USER=emoemo_dev_user
SQL_PASSWORD=emoemo_dev_pass

・・・が、なぜかうまくいかなかった。

emoemo_dev_userでアクセスしようとして失敗していた。

ここで登場する名前付きボリューム

Dockerizing Django with Postgres, Gunicorn, and Nginxを一度写経しつつ環境を構築したが、このリポジトリはまだ同じようになっていないので、改めて見比べて修正した。

修正したものが以下。

services:
  db:
    image: postgres:16.3
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    environment:
      - POSTGRES_USER=emoemo_dev_user
      - POSTGRES_PASSWORD=emoemo_dev_pass
      - POSTGRES_DB=emoemo_dev
  # web: 側が本来は以下に含まれるが割愛
volumes:
  postgres_data:

結論、volumesに関する記述を2箇所修正することでenvironmentに設定したユーザーが作成されて動くようになった。

そして、そもそもこの書き方なんだっけ?と調べたところ、名前付きボリュームというものらしい、とわかった。

名前付きボリュームとは

このボリュームは複数のサービスを横断して再利用可能なものです( volumes_from に依存しません )。

との説明がドキュメントに書かれていた。

https://docs.docker.jp/v1.11/compose/compose-file.html#volume-configuration-reference

この名前付きボリュームを用いると、他のコンテナからもアクセスできるようだった。

そもそも最初は以下のように書いていたが、これはローカルの./data/dbディレクトリをコンテナの/var/lib/postgresql/dataにマウントする、という書き方だった。

volumes:
  - ./data/db:/var/lib/postgresql/data

つまり、ローカルの設定 -> Dockerコンテナの設定 と変わったことによって、設定値が反映されたのだろう、と推測している。

最初はenvironmentに書いた値を使っていた(と勘違いしていた)が、実はユーザー名などに利用しているpostgresは初期設定だったので、うまく行っていなかったのだと理解した。