Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
1
Help us understand the problem. What are the problem?

Docker for Windows で postgres のデータを永続化したい

背景

Docker for Windows で postgres のデータを永続化したい。
こう書いただけだと、ググれば類例はあまたあるわけですが…

単純に /var/lib/postgresql/data をホスト側のパスにマッピングしただけではいろいろエラーが出てまともに動かない。で、 外部ボリュームを使えばいいじゃない という解決策が Windows の場合は一般的なんだろうと思いますが、私の場合、手元の環境の一部が

  • ときどき Docker for Windows が立ち上がらなくなって再インストールを余儀なくされる

んです。これやると、外部ボリュームなんてどこかに吹っ飛んでしまうんですね。何のための永続化なの…(涙)。

最近は WSL2 からも Docker for Windows さわれるようになったし、うまい方法はないかしら…と探していたら、ちゃんとあるじゃないですか。というわけで、以下まとめ。

方法

概要

ちなみに、ここの記述は Docker Hub の postgres の "Arbitrary --user Notes" に書かれている 3 つの回避策のうちの 2 番:

bind-mount /etc/passwd read-only from the host (if the UID you desire is a valid user on your host)

を元にしています。

WSL2 の場合、ユーザの UID も GID も 1000 ですので、 postgres コンテナの中のプロセスが 1000:1000 で動作するようにお膳立てすればよいわけです。

詳細

1. /etc/passwd, /etc/group への UID=1000, GID=1000 の行の追加

postgres コンテナから /etc/passwd, /etc/group を取り出して、そこに UID=1000, GID=1000 の行を追加したものをそれぞれ ./etc/passwd, ./etc/group として保存します。

  • /etc/passwd ... 末尾に UID=1000 の行を加えてあります。
root:x:0:0:root:/root:/bin/ash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/mail:/sbin/nologin
news:x:9:13:news:/usr/lib/news:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucppublic:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
man:x:13:15:man:/usr/man:/sbin/nologin
postmaster:x:14:12:postmaster:/var/mail:/sbin/nologin
cron:x:16:16:cron:/var/spool/cron:/sbin/nologin
ftp:x:21:21::/var/lib/ftp:/sbin/nologin
sshd:x:22:22:sshd:/dev/null:/sbin/nologin
at:x:25:25:at:/var/spool/cron/atjobs:/sbin/nologin
squid:x:31:31:Squid:/var/cache/squid:/sbin/nologin
xfs:x:33:33:X Font Server:/etc/X11/fs:/sbin/nologin
games:x:35:35:games:/usr/games:/sbin/nologin
cyrus:x:85:12::/usr/cyrus:/sbin/nologin
vpopmail:x:89:89::/var/vpopmail:/sbin/nologin
ntp:x:123:123:NTP:/var/empty:/sbin/nologin
smmsp:x:209:209:smmsp:/var/spool/mqueue:/sbin/nologin
guest:x:405:100:guest:/dev/null:/sbin/nologin
nobody:x:65534:65534:nobody:/:/sbin/nologin
postgres:x:70:70:Linux User,,,:/var/lib/postgresql:/bin/sh
utmp:x:100:406:utmp:/home/utmp:/bin/false
hogehoge:x:1000:1000:Linux User,,,:/var/lib/postgresql:/bin/sh
  • /etc/group ... 末尾に GID=1000 の行を加えてあります。
root:x:0:root
bin:x:1:root,bin,daemon
daemon:x:2:root,bin,daemon
sys:x:3:root,bin,adm
adm:x:4:root,adm,daemon
tty:x:5:
disk:x:6:root,adm
lp:x:7:lp
mem:x:8:
kmem:x:9:
wheel:x:10:root
floppy:x:11:root
mail:x:12:mail
news:x:13:news
uucp:x:14:uucp
man:x:15:man
cron:x:16:cron
console:x:17:
audio:x:18:
cdrom:x:19:
dialout:x:20:root
ftp:x:21:
sshd:x:22:
input:x:23:
at:x:25:at
tape:x:26:root
video:x:27:root
netdev:x:28:
readproc:x:30:
squid:x:31:squid
xfs:x:33:xfs
kvm:x:34:kvm
games:x:35:
shadow:x:42:
cdrw:x:80:
usb:x:85:
vpopmail:x:89:
users:x:100:games
ntp:x:123:
nofiles:x:200:
smmsp:x:209:smmsp
locate:x:245:
abuild:x:300:
utmp:x:406:utmp
ping:x:999:
nogroup:x:65533:
nobody:x:65534:
postgres:x:70:postgres
hogehoge:x:1000:hogehoge

2. /etc/passwd, /etc/group をリードオンリーマウントしつつ、 user オプションで UID=GID=1000 を指定してコンテナを起動

私は docker-compose を使っているので docker-compose.yml の記述で示しますが、 docker run の場合も同様です。
下記の例を使う場合は事前に ./data/, ./docker-entrypoint-initdb.d/ フォルダを用意しておくことをお忘れなく。 ./docker-entrypoint-initdb.d/ 配下には、データベースがまだなかった場合(初回起動時)に実行される初期化用のスクリプト(.sh や .sql)を置いておくことができます。

version: '3'

services:
  postgres:
    image: postgres:12-alpine
    user: '1000:1000'
    volumes:
      - ./etc/passwd:/etc/passwd:ro
      - ./etc/group:/etc/group:ro
      - ./data:/var/lib/postgresql/data
      - ./docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
    ports:
      - 5432:5432
    environment:
      POSTGRES_PASSWORD: postgres
    networks:
      mynet:

networks:
  mynet:

こんなところかな。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
1
Help us understand the problem. What are the problem?