はじめに
postgresにおけるvolume設定でいまいち理屈がわかっていなかったので、下記残しメモ
WSL基準での記載となってしまっていますが、他の環境でも同じ考え方で対応できるかと思います。
※ 2023/12/31 フォルダの所有者が原因ではなく、権限が原因であることを再度書き直し(対策としては問題はなかった)
確認環境
- 記載当初
- windows10 pro
- wsl2(20.04.5 LTS (Focal Fossa))
- Dockerのバージョン
- Docker version 20.10.18, build b40c2f6
- docker-compose version 1.29.2, build 5becea4c
- 書き直し時
- WSL2(Ubuntu22.04.3 LTS)
- Docker (24.0.6)
- Docker Compose (2.4.1)
※Docker Desktop ではありません
状況
docker-compose.yml で以下のようにvolume設定をカレントディレクトリ内で設定して docker-compose で up する
version: '3'
services:
pgdb:
image: postgres:14.5
ports:
- 5432:5432
volumes:
- ./data:/var/lib/postgresql/data
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
原因
postgresイメージはGIDが999で動作しているが、WSLで/mnt/... 以下のフォルダにマウントをすると、UID が変更できないので、マウントするフォルダに対して、フォルダ所有者の変更ができずに不具合が起こってしまう(、、みたいです)
DockerfileでGIDを変更してビルドしてみましたが、どうも内部で999になって、外では1000になるのでパーミッションエラーでNGになってしまいます、、(フォルダは777になっているので問題はなさそうなんですが、、)
原因はフォルダの権限でした。/mnt/... 以下のフォルダにバインドマウントをするとパーミッションが777から変更できませんので、Windows管理の保存領域以外の場所を使う必要が出てきます。フォルダのパーミッションは700or750にするべきのようです。(こういうログが出ていました)
postgres-db-1 | 2023-12-31 01:56:53.024 UTC [82] DETAIL: Permissions should be u=rwx (0700) or u=rwx,g=rx (0750).
postgres-db-1 | child process exited with exit code 1
また、フォルダの所有者についてですが、
volumes:
- ./data:/var/lib/postgresql/data`
のようにcomposeを設定して、ホスト側(./data
)の所有者のGID,UIDを1000にして、docker compose up
すると、dataの中身は999のGID,UIDで作成されますが、きちんと起動するし、動作も問題なさそう(基本的なCRUDのSQLは実行可能)なので、あまり関係なさそうです。(とはいえ、所有者1000の中に999のファイルが入っている歪な構成になりますのでお勧めはしませんが、、)
対策
パーミッションを777にするのはやめましょう。
また、WSLではpostgresのマウントをするときは、 /mnt/... のWindows領域は使わないようにしましょう。もしくは、バインドマウントではなく、ボリュームマウントを定義して、そちらで永続化をしましょう、、
※デフォルトのUIDが1000も多い(nodeとか)ので、あまり意識する場面は少ないかと、、
またWSL使用時のときはDockerfileで
RUN groupmod -g 1000 postgres
RUN usermod -u 1000 postgres
を実行すると、歪な構成になることを回避できます。
終わりに
1年くらい色々やってみて、やっと核心っぽいところまたどり着いた気がします。
Dockerのコンテナが動かない原因究明は本当に難しい…