web-dev-qa-db-ja.com

ボリュームを使用して、Docker化されたpostgresデータベースにデータを保持する方法

私のdocker composeファイルには、web、nginx、postgresの3つのコンテナーがあります。 Postgresは次のようになります。

postgres:
  container_name: postgres
  restart: always
  image: postgres:latest
  volumes:
    - ./database:/var/lib/postgresql
  ports:
    - "5432:5432

私の目標は、./databaseというローカルフォルダーに対応するボリュームをpostgresコンテナー内に/var/lib/postgresとしてマウントすることです。これらのコンテナーを起動してpostgresにデータを挿入すると、/var/lib/postgres/data/base/が(postgresコンテナー内で)追加するデータでいっぱいになっていることを確認しますが、ローカルシステムでは./databasedataフォルダーのみを取得します。つまり、./database/dataが作成されます、しかし空です。どうして?

ノート:

更新1

ニックの提案に従って、私はdocker inspectをし、見つけました:

    "Mounts": [
        {
            "Source": "/Users/alex/Documents/MyApp/database",
            "Destination": "/var/lib/postgresql",
            "Mode": "rw",
            "RW": true,
            "Propagation": "rprivate"
        },
        {
            "Name": "e5bf22471215db058127109053e72e0a423d97b05a2afb4824b411322efd2c35",
            "Source": "/var/lib/docker/volumes/e5bf22471215db058127109053e72e0a423d97b05a2afb4824b411322efd2c35/_data",
            "Destination": "/var/lib/postgresql/data",
            "Driver": "local",
            "Mode": "",
            "RW": true,
            "Propagation": ""
        }
    ],

これにより、自分でコーディングしていない別のボリュームによってデータが盗まれているように見えます。なぜそうなのか分かりません。 postgresイメージはそのボリュームを作成しますか?その場合、再起動時にマウントしているボリュームの代わりにそのボリュームを使用する方法はありますか?それ以外の場合、その他のボリュームを無効にして、独自の./databaseを使用する良い方法はありますか?

更新2

ニックのおかげで解決策を見つけました! (および別の友人)以下の回答。

151
Alex Lenail

不思議なことに、解決策は変更することになった

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

volumes:
  - ./postgres-data:/var/lib/postgresql/data
175
Alex Lenail

全てのPostgresデータに共通の ボリューム を作成することができます

 docker volume create pgdata

またはあなたはそれを作成ファイルに設定することができます

   version: "3"
   services:
     db:
       image: postgres
       environment:
         - POSTGRES_USER=postgres
         - POSTGRES_PASSWORD=postgress
         - POSTGRES_DB=postgres
       ports:
         - "5433:5432"
       volumes:
         - pgdata:/var/lib/postgresql/data
       networks:
         - suruse
   volumes: 
     pgdata:

ボリューム名 pgdata を作成し、このボリュームをコンテナのパスにマウントします。

この巻を調べることができます

docker volume inspect pgdata

// output will be
[
    {
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/pgdata/_data",
        "Name": "pgdata",
        "Options": {},
        "Scope": "local"
    }
]
63

相対パスは使用しないでください。 dockerはデーモンとクライアントの関係であることを忘れないでください。

あなたが作成を実行しているとき、それは基本的に単にさまざまなdocker clientコマンドに分割され、それらはその後デーモンに渡されます。その./databaseは、クライアントではなく、 daemon に対して相対的です。

さて、 docker devチームはこの問題に関して前後にいくらか持っています しかし、肝心なのはそれがいくつかの予期しない結果をもたらすことができるということです。

つまり、相対パスではなく絶対パスを使用してください。

6
Nick Burke

最初にdocker create -v /location --nameを使ってdockerの外部にボリュームを作成し、それを再利用する必要があると思います。

そして、私がdockerを多用していた頃には、dockerfile定義で静的dockerボリュームを使用することは不可能でしたので、私の提案はコマンドラインを試すことです(最終的にはスクリプトで)。

2
Joel B