Jak utrwalić dane w zadokowanej bazie danych Postgres przy użyciu woluminów


204

Mój plik komponowania dokera ma trzy kontenery, web, nginx i postgres. Postgres wygląda następująco:

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

Moim celem jest zamontowanie woluminu odpowiadającego folderowi lokalnemu o nazwie ./databasewewnątrz kontenera postgres as /var/lib/postgres. Kiedy uruchamiam te kontenery i wstawiam dane do postgres, sprawdzam, czy /var/lib/postgres/data/base/jest pełne danych, które dodaję (w kontenerze postgres), ale w moim systemie lokalnym ./databasedostaje tylko datafolder, tzn. ./database/dataJest tworzony, ale jest pusty . Czemu?

Uwagi:

AKTUALIZACJA 1

Zgodnie z sugestią Nicka zrobiłem docker inspecti znalazłem:

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

Co sprawia, że ​​wygląda na to, że dane są kradzione przez inny wolumin, którego sam nie kodowałem. Nie jestem pewien, dlaczego tak jest. Czy obraz postgres tworzy dla mnie ten wolumin? Jeśli tak, to czy jest jakiś sposób na użycie tego woluminu zamiast woluminu, który instaluję po ponownym uruchomieniu? W przeciwnym razie, czy istnieje dobry sposób na wyłączenie tego innego woluminu i użycie własnego ./database?

AKTUALIZACJA 2

Znalazłem rozwiązanie, dzięki Nickowi! (i inny przyjaciel) Odpowiedz poniżej.


czy już uruchomiłeś initdbwiersz poleceń, aby zainicjować klaster bazy danych?
Sebastian Webber

Czy na pewno Twój podkatalog danych jest naprawdę pusty? Może mieć specjalne uprawnienia dostępu.
Yaroslav Stavnichiy

Dzięki, że tak szybko do mnie wróciłeś! Używam app kolby, więc from app import dbi db.create_all()od A docker runpo uruchomieniu pojemników. Nie initdbbezpośrednio z wiersza poleceń.
Alex Lenail

1
@YaroslavStavnichiy Nie wiem, jak inaczej to sprawdzić sudo su -i zajrzeć ./database/data. O ile mi wiadomo, nic tam nie ma.
Alex Lenail

Ktoś może uznać to za użyteczne: przykładowy plik z ciągłym postgres, elastyczne wyszukiwanie i dane medialne, stackoverflow.com/a/56475980/5180118
ArdentLearner

Odpowiedzi:


252

O dziwo, rozwiązanie ostatecznie uległo zmianie

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

do

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

45
Krótkie „dlaczego” dla tej odpowiedzi (która działa). Według osób postgresowych domyślnym katalogiem danych jest /var/lib/postgresql/data- notatki ze zmiennymi PGDATA można znaleźć tutaj: store.docker.com/images/…
Matt Pavelle

2
W powyższym pytaniu OP twierdzi, że zadziałało dla niego bez danych / na końcu. Czy to jest poprawne?
Sid

2
I dodaj lokalny katalog do swojego .dockerignorepliku, szczególnie jeśli kiedykolwiek przycinasz go do obrazu produkcyjnego. Zobacz codefresh.io/blog/not-ignore-dockerignore do dyskusji.
dsz

4
to nadal nie działa dla mnie (mac os x high sierra)
olidem

1
@ OlliD-Metz Musiałem zrobić docker rm my_postgres_container_1zanim to zadziałało (także High Sierra).
bogaty

100

Możesz utworzyć wspólny wolumin dla wszystkich danych Postgres

 docker volume create pgdata

lub możesz ustawić go na plik tworzenia

   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:

Utworzy wolumin o nazwie pgdata i zamontuje ten wolumin na ścieżce kontenera.

Możesz sprawdzić ten wolumin

docker volume inspect pgdata

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

8
Komentowanie trochę spóźnione, ale nie wyczyści danych, jeśli to zrobię docker-compose down -v. A jakie jest na to rozwiązanie?
Sid

3
@Sid, tak, będzie! Bądź ostrożny z tą opcją.
olidem

1
więc z dokerem-komponuj [w dół] głośność nie jest już utrzymywana? Czy pełne czyszczenie jest nawet w przypadku woluminu?
Paul

2
@Sid Komentując nawet później, ale można używać docker-compose down --rmi all bez tej -vopcji i będzie ona pozbyć się „wszystko” z wyjątkiem wielkości, czyli pojemniki, sieci, obrazy, itd. To zrobić podczas wdrażania jednocześnie umożliwiając utrzymywanie danych.
code_dredd

13

Unikałbym używania ścieżki względnej. Pamiętaj, że doker jest relacją demon / klient.

Kiedy wykonujesz komponowanie, zasadniczo dzieli się ono na różne polecenia klienta dokera, które są następnie przekazywane do demona. Jest ./databaseto następnie względne względem demona , a nie klienta.

Obecnie zespół deweloperów dokerów ma w tej kwestii trochę do przodu , ale najważniejsze jest to, że może przynieść nieoczekiwane rezultaty.

Krótko mówiąc, nie używaj ścieżki względnej, użyj ścieżki bezwzględnej.


Dzięki za tę odpowiedź! Niestety nie sądzę, żeby zadziałało. Zmieniłem wiersz na ścieżkę bezwzględną, a po wstawieniu danych database/datafolder jest nadal pusty = (
Alex Lenail,

K. Kolejnym krokiem jest uruchomienie docker inspectkontenera i upewnienie się, że kontener jest świadomy woluminu (na wypadek gdyby kompozycja była pomylona lub coś takiego). (uwaga: inspekcja dokerów może mieć wrażliwe dane, więc nie wklejaj ich tutaj bez mungowania ;-) Potem chodzi o sprawdzenie uprawnień (chociaż zwykle to pokazuje błąd)
Nick Burke

Aha! @Nick Burke Myślę, że coś znalazłeś. Zaktualizowałem pytanie.
Alex Lenail

2

Myślę, że najpierw musisz utworzyć wolumin poza dokerem, docker create -v /location --namea następnie użyć go ponownie.

Do czasu kiedy często używałem Dockera, nie było możliwe użycie statycznego woluminu Dockera z definicją pliku Docker, więc sugeruję wypróbowanie wiersza poleceń (ewentualnie ze skryptem).


0

Miałem ten sam problem od wielu dni. Mój przypadek był po prostu literówką: „postgresql” ma tylko jeden „s”, napisałem dwa (postgressql): $.


Co sprawia, że ​​myślisz, że ta sama literówka wystąpiła u osoby, która zadała pytanie, biorąc pod uwagę, że literówka, do której się odwołujesz, nie pojawia się w jej pytaniu?
Jason Aller
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.