LoginSignup
34
17

More than 1 year has passed since last update.

docker-composeでpostgresのDBが永続化できていなかったのを直した

Last updated at Posted at 2022-03-09

問題

今いるプロジェクトで、docker-composeで名前付きvolumeを使っているのにも関わらず、postgresのDBが永続化できませんでした。
なので、docker-compose downをするとDBが消えてしまい、docker-compose upした後にその都度rake db:createやらrake db:migrateをやりなおさないといけないという感じでした。

まぁ、そんな頻繁にdocker-compose downしなければいいとはいえ、たまにdocker-compose downした時にいちいちDBを作成しなおすのは面倒ですし、必要なデータが存在する場合はDBを削除できないので、誤ってdocker-compose downしないように気をつけないといけません。

余計な部分は省いていますが、当初のdocker-compose.ymlは以下のような感じでした。
( postgresのDBを永続化するために、名前付きvolumeを作成して、postgresコンテナ内の/var/lib/postgresqlとマウントしています)

docker-compoe.yml
version: '3'
services:

  postgres:
    environment:
     - (略)
    image: postgres:10.5-alpine
    volumes:
      - postgres_volume:/var/lib/postgresql # <名前付きvolume名>:マウントしたいコンテナ内のPATH
    ports:
      - "5432:5432"

volumes:
  postgres_volume: # 名前付きvolumeを定義

postgresコンテナの情報をdocker inspectで確認してみると、勝手に匿名ボリューム(anonymous volume)が作成されpostgresコンテナとマウントしているのがわかりました。。うーむ、名前付きvolumeを指定してるんだけどなー:thinking:

docker inspect <コンテナID>

解決方法

結論から言うと、volumesプロパティで指定しているコンテナ側のPATHが誤っていました。

【誤】 postgres_volume:/var/lib/postgresql
【正】 postgres_volume:/var/lib/postgresql/data

解説

postgresのDockerfileにあるVOLUME命令

Dockerhubにて、postgresDockerfileを見ると原因がわかります。
postgresDockerfileに以下の記述があります。

VOLUME [/var/lib/postgresql/data]

VOLUME命令とは?

Dockerfileで、VOLUME命令を指定すると匿名volumeが自動で作成されるそうです。

なぜ解決した?

再度以下を見てください。

【誤】 postgres_volume:/var/lib/postgresql
【正】 postgres_volume:/var/lib/postgresql/data

上記の記事によれば、DockerfileVOLUME命令で指定されているPATHと同じPATHを、名前付きvolumeのマウント先として指定すると、匿名volumeが作成されず、名前付きvolumeが使用される挙動になるそうです。
実際に試した所そのような挙動となることを確認しました。

なので、DBが永続化できていなかった原因は、docker-compose.ymlにて、名前付きボリュームがマウントするpostgresコンテナのPATHの指定が間違っていたことでした。

補足

匿名ボリュームが作成されてるので、永続化できそうな気もしますが、実際のところ匿名ボリュームはコンテナを削除して作成するたびに作られいて、使い回されないみたいです。
ただ過去の匿名ボリュームは使い回されないだけで、ずっと残りつづけていて、ストレージを逼迫する原因になります。
自分は過去の匿名ボリュームだけでMACのストレージを50GBくらい使ってました:sweat_smile:

以下でvolume一覧が確認可能です。

docker volume ls

不要なvolumeを削除したい場合は以下のコマンドでできます。(現在存在するコンテナと紐付いてないvolumeのみ削除)

docker volume rm $(docker volume ls -qf dangling=true)

参考

34
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
34
17