it-swarm.com.de

So speichern Sie Daten in einer dockerisierten Postgres-Datenbank mithilfe von Volumes

Meine Docker-Compose-Datei enthält drei Container: Web, Nginx und Postgres. Postgres sieht so aus:

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

Mein Ziel ist es, ein Volume, das einem lokalen Ordner namens ./database entspricht, im Postgres-Container als /var/lib/postgres bereitzustellen. Wenn ich diese Container starte und Daten in postgres einfüge, stelle ich sicher, dass /var/lib/postgres/data/base/ voll mit den Daten ist, die ich hinzufüge (im postgres-Container), aber in meinem lokalen System erhält ./database nur ein data Ordner darin, dh ./database/data wird erstellt, ist aber leer. Warum?

Anmerkungen:

UPDATE 1

Per Nicks Vorschlag habe ich einen docker inspect gemacht und festgestellt:

    "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": ""
        }
    ],

Wie es scheint, werden die Daten von einem anderen Volume gestohlen, das ich nicht selbst codiert habe. Ich weiß nicht, warum das so ist. Erstellt das Postgres-Image dieses Volume für mich? Wenn ja, gibt es eine Möglichkeit, dieses Volume anstelle des Volumes zu verwenden, das ich beim Neustart einbinde? Andernfalls gibt es eine gute Möglichkeit, dieses andere Volume zu deaktivieren und mein eigenes zu verwenden, ./database?

UPDATE 2

Ich habe die Lösung gefunden, danke an Nick! (und ein anderer Freund) Antwort unten.

151
Alex Lenail

Seltsamerweise bestand die Lösung darin, sich zu ändern

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

zu

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

Sie können ein gemeinsames Volumen für alle Postgres-Daten erstellen

 docker volume create pgdata

oder Sie können es auf die Compose-Datei einstellen

   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:

Es wird der Datenträgername pgdata erstellt und dieser Datenträger in den Pfad des Containers geladen.

Sie können dieses Volume überprüfen

docker volume inspect pgdata

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

Ich würde es vermeiden, einen relativen Pfad zu verwenden. Denken Sie daran, dass Docker eine Daemon/Client-Beziehung ist.

Wenn Sie das Compose ausführen, wird es im Wesentlichen in verschiedene Docker-Client-Befehle aufgeteilt, die dann an den Daemon übergeben werden. Das ./database ist dann relativ zum Daemon , nicht zum Client.

Nun, das Docker-Entwicklerteam hat einiges hin und her zu diesem Thema , aber unter dem Strich kann es zu unerwarteten Ergebnissen kommen.

Kurz gesagt, verwenden Sie keinen relativen Pfad, sondern einen absoluten Pfad.

11
Nick Burke

Ich denke, Sie müssen nur Ihr Volume außerhalb Docker zuerst mit einem docker create -v /location --name erstellen und dann wiederverwenden.

Und zu der Zeit, als ich Docker häufig verwendete, war es nicht möglich, ein statisches Docker-Volume mit Docker-Dateidefinition zu verwenden. Mein Vorschlag ist daher, die Befehlszeile zu verwenden (eventuell mit einem Skript).

2
Joel B