この記事の目的
この記事では、
Docker for Windowsでpostgesのデータディレクトリを
Windowsのディレクトリにマウントしようとして
頑張ったときの情報をまとめること
を目的としています。
本題
★要約
ことのはじまり
「ローカル環境にPostgresの環境を構築したい。」
「どこでも同じ環境を構築できるようにしたい。」
「Postgresをローカル環境に入れたくない。」
という気持ちから、PostgresをDockerで用意することにしました。
この時、データの永続化は別に必須ではなかったですが、
できることなら永続化しておこうと思ったのが、このトラブルの発端です。
起こった現象
任意の場所にPostgresのデータをマウントするためのディレクトリを作成し、
そこにマウントするようにDocker runしました。
mkdir C:\postgres docker run -d -v "C:\postgres":/var/lib/postgresql/data postgres:11.3
陽気に↑を実行すると、以下のエラーが発生し、
指定したディレクトリに一瞬現れたpostgresのデータファイルが消されました。
running bootstrap script ... 2019-06-14 06:49:00.898 UTC [77] FATAL:
data directory "/var/lib/postgresql/data" has wrong ownership2019-06-14 06:49:00.898 UTC [77] HINT:
The server must be started by the user that owns the data directory.child process exited with exit code 1
initdb: removing contents of data directory "/var/lib/postgresql/data"
結論
とりあえず、先に結論的対応をまとめておきます。
Step1)対象のDocker Volumeを作成する。
※明示的に作成しなくても、なければDocker run時に勝手に作ってくれます。
[volume name]は任意の値を入れます。ここでは、db-data という名前で進めました。
Docker create volume [volume name]
Step2)Docker runする
docker run -d -v db-data:/var/lib/postgresql/data postgres:11.3
これで、作成されたコンテナの/var/lib/postgresql/dataディレクトリが、
Docker Volumeのdb-dataにマウントされ、
コンテナを消しても、データが消えない(永続化)ができるようになりました。
めでたしめでたし・・・?
★補足情報
そもそも/var/lib/postgrsql/dataがマウントできなかった原因について
GithubのIssueから、Docker for Windows では、
特定の権限を持つディレクトリをマウントできないということと、
ほかにも同じ現象で困っていることがわかりました(/・ω・)/
技術的な原因は把握できていませんが、これがすべて・・・なのかな。
For the time being, this won't work.
You should either just use in-container storage or use a volume not mounted from your Windows host.
docker volumeのdb-dataの実体
無事にデータを永続化しながらdocker runをすることができましたが、
永続化したファイルたちはどこにいるのか。
という点についてもう少し探ってみました。
docker volumeの詳細な設定情報は、以下のコマンドで確認することができます。
docker volume ls >DRIVER VOLUME NAME >local db-data docker volume inspect db-data >[ > { > "CreatedAt": "2019-06-14T06:34:48Z", > "Driver": "local", > "Labels": null, > "Mountpoint": "/var/lib/docker/volumes/db-data/_data", > "Name": "db-data", > "Options": null, > "Scope": "local" > } >]
この情報から、どこかしらの
"/var/lib/docker/volumes/db-data/_data"ディレクトリ
にマウントされていることがわかります。
Docker for WindowsのLinux用機能は、Hyper-v上に構築された
MobyLinuxVMというマシン上で動いています。
そのため、上記で得られたディレクトリは、
MobyLinuxVMのディレクトリであるということがわかります。
ここで、MobyLinuxVMマシンに入って実際のディレクトリを確認したい気持ちが出てきました。
Hyper-vマネージャーから接続できるかと思いきや、そんなことはできませんでした。
そのため、この記事を参考にして、コンテナのホストへアクセスしてみました。
qiita.com
記事に従い、Dockerfileを作成し、コンテナにアクセスしたときの状態がこちらになります。
docker run -it --privileged --pid=host hostenter /bin/sh / # ls >EFI dev lib proc sendtohost usr >bin etc media root srv var >boot home mnt run sys >containers init opt sbin tmp
ホストの名前空間に特権ユーザーでアクセスしているため、
以下のディレクトリが参照できるようになっているらしいです。
正直ここら辺はあやふやです(;´Д`)
EFI、sendtohost、varboot、containers、init
目的のpostgresのデータは、"/var/lib/docker/volumes/db-data/_data"にあるので、
dockerコンテナにアクセスした状態で、中を確認してみます。
ls /var/lib/docker/volumes/db-data/_data >PG_VERSION pg_ident.conf pg_snapshots pg_wal >base pg_logical pg_stat pg_xact >global pg_multixact pg_stat_tmp postgresql.auto.conf >pg_commit_ts pg_notify pg_subtrans postgresql.conf >pg_dynshmem pg_replslot pg_tblspc postmaster.opts >pg_hba.conf pg_serial pg_twophase postmaster.pid
無事、マウントされたファイルたちを見ることができました。
マウントされたファイルに何かする用事はないですが、
実体がどこにあるか確認しないと不安でしょうがないときは、
こうやって確認することができますね!
その他の方法について
※失敗した方法です。
postgresでも、ほかのディレクトリ(ex. /mnt)は、Windowsのディレクトリでマウントすることができます。ということは、postgresのイメージを実行する前に、問題となっているディレクトリの権限、所有者、所有グループをまとめて変更しておけばマウントできるのではないかと考えました。
//postgresのコンテナにアクセスしたときのフォルダ権限の状態 //問題のディレクトリ root@ee8c8156c478:/# ls -ld /var/lib/postgresql/data >drwxrwxrwx 2 root root 8192 Jun 14 07:46 /var/lib/postgresql/data //問題のディレクトリの親ディレクトリ root@ee8c8156c478:/# ls -ld /var/lib/postgresql/ drwxr-xr-x 1 postgres postgres 4096 Jun 10 23:51 /var/lib/postgresql/ //マウントできるディレクトリ root@ee8c8156c478:/# ls -ld /mnt drwxr-xr-x 2 root root 4096 Jun 10 00:00 /mnt
結果、このアプローチでは、同じエラーが発生したため、うまくいきませんでした。。。