ボリュームを使用してドッキングされたpostgresデータベースにデータを保持する方法


205

私の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コンテナーに)いっぱいであることを確認しますが、ローカルシステムで./databaseは、dataフォルダーを取得するだけです(つまり./database/data、作成されますが、空です) 。どうして?

ノート:

アップデート1

ニックの提案に従って、私はa 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

私はニックのおかげで解決策を見つけました!(および別の友人)以下で答えてください。


initdbコマンドラインを実行してデータベースクラスターを初期化しましたか?
セバスチャンウェバー

データサブディレクトリが本当に空ですか?特別なアクセス許可がある場合があります。
Yaroslav Stavnichiy 2017年

早く返信してくれてありがとう!私は私ので、フラスコのアプリを使用していますfrom app import dbし、db.create_all()からdocker runコンテナを開始した後。initdbコマンドラインから直接操作することはありません。
Alex Lenail 2017年

1
私はそれより確認する方法を他に知らない@YaroslavStavnichiy sudo su -で、ルックを./database/data。私の知る限り、そこには何もありません。
Alex Lenail 2017年

誰かがこれを便利だと思うかもしれません:postgres、エラスティック検索、メディアデータを保持するサンプル構成ファイル、stackoverflow.com
a / 56475980/5180118

回答:


254

不思議なことに、解決策は最終的に変化することになった

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

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

45
この回答の簡単な「理由」(これは機能します)。postgresによると、デフォルトのデータディレクトリは-PGDATA/var/lib/postgresql/data変数のメモをここで読むことができます:store.docker.com/images/…–
Matt

2
上記の質問で、OPは/ dataが最後になくても動作することを述べています。あれは正しいですか?
2017年

2
また、ローカルディレクトリを.dockerignoreファイルに追加します。これを運用イメージに変換する場合は特にそうです。議論については、codefresh.io / blog / not-ignore-dockerignoreを参照してください。
dsz 2017

4
これはまだ機能しません(mac os x high sierra)
olidem

1
@ OlliD-Metz動作するdocker rm my_postgres_container_1前に(High Sierraも)実行しなければなりませんでした。
リッチ

100

すべての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"
    }
]

8
少し遅れてコメントしますが、これを行うと、データが明確になりませんdocker-compose down -v。そして、それに対する解決策は何ですか?
シド

3
@シド、はい、そうします!このオプションには注意してください。
2018年

1
だからdocker-compose [down]でボリュームはもはや永続化されませんか?ボリュームも完全にクリーンアップしますか?
ポール、

2
@Sidコメントは後で行うことdocker-compose down --rmi all できます-vオプションなしで使用でき、ボリューム以外の「すべて」、つまり、コンテナー、ネットワーク、イメージなどをクリアします。データの永続化を許可しながら展開する場合は、そうします。
code_dredd

13

相対パスの使用は避けます。dockerはデーモンとクライアントの関係であることに注意してください。

作成を実行しているときは、基本的には、さまざまなDockerクライアントコマンドに分解され、デーモンに渡されます。これ./databaseは、クライアントではなくデーモンに関連しています。

現在、Docker開発チームはこの問題について前後していますが、結論として予期しない結果が生じる可能性があります。

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


この回答をありがとう!残念ながら、うまくいかなかったと思います。行を絶対パスに変更しましたが、データを挿入した後もdatabase/dataフォルダーは空です=(
Alex Lenail

K.次にdocker inspect、コンテナーで実行して、コンテナーがボリュームを認識していることを確認します(作成が混乱した場合などに備えて)。(注:docker inspectには機密データが含まれている可能性があるため、変更せずにここに貼り付けないでください;-)その後、権限を確認するだけです(ただし、通常はエラーが表示されます)
Nick Burke

ああ!@ニックバーク私はあなたが何かを見つけたと思います。質問を更新しました。
Alex Lenail 2017年

2

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

そして、私がdockerをよく使用するまでに、dockerfile定義で静的なdockerボリュームを使用することはできなかったので、私の提案はコマンドライン(最終的にはスクリプトを使用)を試すことです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.