Come conservare i dati in un database postgres dockerizzato usando i volumi


205

Il mio file di composizione docker ha tre contenitori, web, nginx e postgres. Postgres si presenta così:

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

Il mio obiettivo è montare un volume corrispondente a una cartella locale chiamata ./databaseall'interno del contenitore postgres come /var/lib/postgres. Quando avvio questi contenitori e inserisco i dati in Postgres, verifico che /var/lib/postgres/data/base/sia pieno dei dati che sto aggiungendo (nel contenitore Postgres), ma nel mio sistema locale, contiene ./databasesolo una datacartella, cioè ./database/dataviene creato, ma è vuoto . Perché?

Appunti:

AGGIORNAMENTO 1

Per suggerimento di Nick, ho fatto un docker inspecte ho trovato:

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

Il che fa sembrare che i dati vengano rubati da un altro volume che non ho codificato. Non sono sicuro del perché. L'immagine di Postgres sta creando quel volume per me? In tal caso, esiste un modo per utilizzare quel volume invece del volume che sto montando al riavvio? In caso contrario, c'è un buon modo di disabilitazione che altro volume e utilizzando il mio, ./database?

AGGIORNAMENTO 2

Ho trovato la soluzione, grazie a Nick! (e un altro amico) Rispondi sotto.


esegui già la initdbriga di comando per inizializzare il tuo cluster di database?
Sebastian Webber,

Sei sicuro che la tua sottodirectory dei dati sia davvero vuota? Potrebbe avere autorizzazioni di accesso speciali.
Yaroslav Stavnichiy,

Grazie per essere tornato da me così in fretta! Sto usando un'app di pallone, quindi io from app import dbe db.create_all()da docker rundopo aver avviato i contenitori. Non lo faccio initdbdirettamente dalla riga di comando.
Alex Lenail,

1
@YaroslavStavnichiy Non so come altro controllarlo sudo su -e guardarlo ./database/data. Non c'è niente lì dentro per quanto posso dire.
Alex Lenail,

Qualcuno potrebbe rivelarsi utile: file di esempio composizione persistente Postgres, elasticsearch e dati multimediali, stackoverflow.com/a/56475980/5180118
ArdentLearner

Risposte:


254

Stranamente, la soluzione è stata quella di cambiare

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

per

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

45
Solo un "perché" veloce per questa risposta (che funziona). Per la gente di postgres, la directory dei dati predefinita è /var/lib/postgresql/data- puoi leggere le note della variabile PGDATA qui: store.docker.com/images/…
Matt Pavelle

2
Nella domanda sopra, l'OP dice che ha funzionato per lui senza i / dati alla fine. È corretto?
Sid,

2
E aggiungi la directory locale al tuo .dockerignorefile, specialmente se la troncerai mai in un'immagine di produzione. Vedi codefresh.io/blog/not-ignore-dockerignore per una discussione.
dsz,

4
questo non funziona ancora per me (mac os x high sierra)
olidem

1
@ OlliD-Metz ho dovuto fare una cosa docker rm my_postgres_container_1prima che funzionasse (anche High Sierra).
ricco

101

Puoi creare un volume comune per tutti i dati di Postgres

 docker volume create pgdata

oppure puoi impostarlo sul file di composizione

   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:

Creerà il nome del volume pgdata e monterà questo volume sul percorso del contenitore.

Puoi controllare questo volume

docker volume inspect pgdata

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

8
Commentando un po 'in ritardo, ma non chiarirò questi dati se lo faccio docker-compose down -v. E qual è la soluzione a questo?
Sid,

3
@Sid, sì, lo sarà! Fai solo attenzione con questa opzione.
olidem,

1
quindi con docker-compose [down] il volume non è più persistente? Una pulizia completa anche del volume?
Paul,

2
@Sid Commentando anche più tardi, ma è possibile utilizzare docker-compose down --rmi all senza l' -vopzione e cancellerà "tutto" tranne i volumi, ovvero contenitori, reti, immagini, ecc. Lo faccio quando si distribuisce consentendo la persistenza dei dati.
code_dredd

13

Eviterei di usare un percorso relativo. Ricorda che la finestra mobile è una relazione demone / client.

Quando si esegue la composizione, essenzialmente si scompone in vari comandi client docker, che vengono quindi passati al demone. Questo ./databaseè quindi relativo al demone , non al client.

Ora, il team di sviluppo docker ha un po 'avanti e indietro su questo problema , ma la linea di fondo è che può avere alcuni risultati inaspettati.

In breve, non utilizzare un percorso relativo, utilizzare un percorso assoluto.


Grazie per questa risposta! Purtroppo, non penso che abbia funzionato. Ho cambiato la linea in un percorso assoluto e dopo aver inserito i dati, la database/datacartella è ancora vuota = (
Alex Lenail

K. Il prossimo è eseguire docker inspectsul contenitore e assicurarsi che il contenitore sia a conoscenza del volume (nel caso in cui la composizione sia confusa o qualcosa del genere). (nota: docker inspect può avere dati sensibili, quindi non incollarli qui senza munging ;-) Dopodiché, si tratta di controllare le autorizzazioni (anche se in genere ciò mostrerebbe un errore)
Nick Burke,

Aha! @ Nick Burke Penso che tu abbia trovato qualcosa. Ho aggiornato la domanda.
Alex Lenail,

2

Penso che devi solo creare il tuo volume fuori dalla finestra mobile prima con un docker create -v /location --namee poi riutilizzarlo.

E quando usavo molto la finestra mobile, non era possibile utilizzare un volume finestra mobile statico con definizione dockerfile, quindi il mio suggerimento è di provare la riga di comando (eventualmente con uno script).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.