web-dev-qa-db-ja.com

既存のデータでPostgreSQLコンテナを使用する方法は?

PostgreSQLコンテナを設定しようとしています( https://hub.docker.com/_/postgres/ )。現在のPostgreSQLインスタンスからのデータがあります。 /var/lib/postgresql/dataからコピーし、PostgreSQLコンテナへのボリュームとして設定したい。

PostgreSQLに関するdocker-compose.ymlファイルの一部:

db:
    image: postgres:9.4
    ports:
        - 5432:5432
    environment:
        POSTGRES_PASSWORD: postgres
        POSTGRES_USER: postgres
        PGDATA : /var/lib/postgresql/data
    volumes:
        - /projects/own/docker_php/pgdata:/var/lib/postgresql/data

Docker-composeを作成すると、次のメッセージが表示されます。

db_1  | initdb: directory "/var/lib/postgresql/data" exists but is not empty
db_1  | If you want to create a new database system, either remove or empty
db_1  | the directory "/var/lib/postgresql/data" or run initdb
db_1  | with an argument other than "/var/lib/postgresql/data".

コンテナから独自のイメージを作成しようとしたため、Dockerfileは次のようになります。

FROM postgres:9.4
COPY pgdata /var/lib/postgresql/data

しかし、私は同じエラーを受け取りました、私は何を間違っていますか?

更新

Pg_dumpallを使用してSQLを取得し、/ docker-entrypoint-initdb.dに配置しましたが、このファイルはdocker-compose upを実行するたびに実行されます。

37
Albert Tobac

Irakliの答えに基づいて、更新されたソリューションを次に示します。

  • 新しいバージョン2 Docker Composeファイルを使用する
  • 別のvolumesセクション
  • 追加の設定が削除されました

docker-compose.yml

version: '2'

services:
  postgres9:
    image: postgres:9.4
    expose:
      - 5432
    volumes:
      - data:/var/lib/postgresql/data

volumes:
  data: {}

デモ

Postgresデータベースサーバーを起動します。

$ docker-compose up

データベース内のすべてのテーブルを表示します。別のターミナルで、コンテナのPostgresと話します:

$ docker exec -it $(docker-compose ps -q postgres9 ) psql -Upostgres -c '\z'

データベースが空なので、何も表示されません。テーブルを作成します。

$ docker exec -it $(docker-compose ps -q postgres9 ) psql -Upostgres -c 'create table beer()'

新しく作成されたテーブルをリストします。

$ docker exec -it $(docker-compose ps -q postgres9 ) psql -Upostgres -c '\z'

                         Access privileges
 Schema |   Name    | Type  | Access privileges | Column access privileges 
--------+-----------+-------+-------------------+--------------------------
 public | beer      | table |                   | 

わーい!共有ストレージボリュームを使用してPostgresデータベースを開始し、その中にいくつかのデータを保存しました。次のステップでは、サーバーが停止した後、データが実際に残っていることを確認します。

次に、Postgresサーバーコンテナーを強制終了します。

$ docker-compose stop

Postgresコンテナを再度起動します。

$ docker-compose up

データベースサーバーがストレージを再利用することを期待しているため、非常に重要なデータはまだそこにあります。小切手:

$ docker exec -it $(docker-compose ps -q postgres9 ) psql -Upostgres -c '\z'
                         Access privileges
 Schema |   Name    | Type  | Access privileges | Column access privileges 
--------+-----------+-------+-------------------+--------------------------
public | beer      | table |                   | 

新しいスタイルのDocker Composeファイルを使用して外部データボリュームを使用してPostgresデータベースを正常に実行し、データが安全で健全であることを確認しました。

データを保存する

まず、バックアップを作成し、ホストにデータを保存します。

$ docker exec -it $(docker-compose ps -q postgres9 ) pg_dump -Upostgres > backup.sql

ゲストデータベースからデータを削除します。

$ docker exec -it $(docker-compose ps -q postgres9 ) psql -Upostgres -c 'drop table beer'

(ホストに保存されている)バックアップをPostgresコンテナーに復元します。

注:use "exec -i"、not "-it"そうでなければ、「入力デバイスはTTYではありません」というエラーが表示されます。

$ docker exec -i $(docker-compose ps -q postgres9 ) psql -Upostgres < backup.sql

テーブルをリストして、復元が機能したことを確認します。

$ docker exec -it $(docker-compose ps -q postgres9 ) psql -Upostgres -c '\z'
                         Access privileges
Schema |   Name    | Type  | Access privileges | Column access privileges 
--------+-----------+-------+-------------------+--------------------------
public | beer      | table |                   | 

要約すると、データベースを起動できること、再起動後もデータが保持されること、ホストからバックアップを復元できることを確認しました。

トマスに感謝します!

50
johntellsall

PostgreSQLイメージには、マウントされたボリュームに問題があるようです。 FWIWは、おそらくDockersよりもPostgreSQLの問題の方が多いでしょうが、とにかくデータベースファイルを保持するためのディスクのマウントは推奨されないため、問題ではありません。

代わりに、データのみのDockerコンテナを作成する必要があります。このような:

postgres9:
  image: postgres:9.4
  ports:
    - 5432:5432
  volumes_from:
    - pg_data
  environment:
    POSTGRES_PASSWORD: postgres
    POSTGRES_USER: postgres
    PGDATA : /var/lib/postgresql/data/pgdata

pg_data:
  image: Alpine:latest
  volumes:
    - /var/lib/postgresql/data/pgdata
  command: "true"

テストして問題なく動作しました。データ専用コンテナーの詳細については、こちらをご覧ください:なぜDockerデータコンテナー(ボリューム!)が良いのか

初期データをインポートする方法については、次のいずれかを実行できます。

  1. docker cp、セットアップのデータ専用コンテナへ、または
  2. バイナリファイルを移動する代わりに、データのSQLダンプを使用します(これは私が行うことです)。
10
irakli