Esecuzione di PostgreSQL utilizzando Docker Compose

Esecuzione di PostgreSQL utilizzando Docker Compose
Docker-compose può essere utilizzato per automatizzare facilmente le distribuzioni multi-container. Uno dei compiti più impegnativi durante l'esecuzione di tali distribuzioni è separare i dati dal software.

Mentre i contenitori sono effimeri, i dati dell'utente devono persistere. Un esempio classico, di questo è quando proviamo a eseguire immagini del contenitore del database. Se si distrugge il contenitore del database, anche i dati vengono persi. Quello che vogliamo è una situazione in cui l'immagine del contenitore di, per esempio, la versione 9 di PostgreSQL può essere sostituita con un'immagine della versione 10 senza che dobbiamo perdere alcun dato. Questo è il modo Docker di aggiornare il software, non si lascia cadere all'interno del contenitore e aggiornare i pacchetti utilizzando un gestore pacchetti. Sostituisci l'intera immagine del contenitore.

Vediamo alcune insidie ​​che potresti incontrare mentre lo fai e come possiamo rendere il processo molto più fluido e pulito dal punto di vista operativo.

Prerequisiti

  1. Un'installazione Docker
  2. Comprensione di base di Docker CLI e Docker-Opse

Volumi Docker e comportamento predefinito di PostgreSQL

I volumi Docker sono il modo consigliato per persistere. Questi sono i file system gestiti dal demone Docker e il più delle volte è previsto di crearne uno e montare all'interno del tuo contenitore quando lo si lancia. L'immagine ufficiale di Postgres, tuttavia, viene fornita con un volume predefinito nella sua descrizione dell'immagine.

Ciò significa che quando si esegue un'immagine PostgreSQL come contenitore, crea un volume per se stesso e memorizza i dati lì dentro.

$ Docker run -d --name mydb postgres

È possibile elencare i volumi esistenti utilizzando il comando Docker Volume LS e puoi ispezionare il contenitore Docker MyDB per vedere quale di questi volumi è montato all'interno del contenitore del database.

$ Docker Volume LS
Nome volume del driver
Locale 8328940661C0703ED867B004EA6343B9432E70069280B71CFCE592ECDD12E55D
$ Docker Ispezionare MyDB
..
"Monte": [

"Tipo": "Volume",
"Nome": "8328940661C0703ED867B004EA6343B9432E70069280B71CFCE592ECDD12E55D",
"Fonte": "/var/lib/docker/volumes/8328940661c0703ed867b004a6343b9432e70069280b71cf
CE592ECDD12E55D/_DATA ",
"Destinazione": "/var/lib/postgresql/dati",
"Driver": "Local",
"Modalità": "",
"RW": vero,
"Propagazione": ""

",
..

Noterai che il volume ha un nome piuttosto ostile ed è montato /var/lib/postgresql/dati.

Rimuoviamo questo contenitore e il volume associato per ora:

$ Docker rm -f mydb
$ Docker Volume RM 8328940661C0703ED867B004EA6343B9432E70069280B71CFCE592ECDD12E55D

Lo stesso vale quando si crea un contenitore utilizzando un semplice file Docker-Onse. Di seguito è riportato un documento.File YML inserito all'interno di una directory denominata Postgres.

Versione: '3'
Servizi:
mydb:
Immagine: Postgres

È possibile alimentarlo a Docker-Opse, aprendo un terminale nella stessa directory in cui questo file è ed in esecuzione:

$ Docker -Opse Up -D

Questo crea un contenitore e un volume molto simile al comando Docker Run che abbiamo visto prima. Tuttavia, entrambi questi metodi, uno che coinvolge Docker-Opse e un altro Docker CLI hanno un problema fatale e questo è in gioco quando è necessario sostituire la vecchia immagine di Postgres con una nuova.

Nuovi volumi ogni volta

Se rimuovi la distribuzione sopra eseguita:

$ Docker-compone

Il contenitore e la rete vengono rimossi ma il volume si attacca e i tuoi dati sono sicuri al suo interno. Tuttavia, la prossima volta che corri:

$ Docker -Opse Up -D

Compose creerà un nuovo volume e un monte che invece di utilizzare il volume precedentemente creato. E come può ricordare che il volume precedente era pensato per questo particolare contenitore postgresql? Ma il povero utente che potrebbe non essere nemmeno consapevole del concetto di volumi sarà confuso chiedendosi dove tutti i dati sono andati.

Volume definito dall'utente

Per aggirare questo problema, possiamo usare le informazioni che abbiamo raccolto in precedenza che ci hanno mostrato che il volume è montato /var/lib/postgresql/dati. All'interno del contenitore, questa directory è dove Postgres memorizza tutte le tabelle e i database pertinenti.

Ora dobbiamo definire un volume all'interno del file di composizione e montarlo in questo punto di montaggio. Questo è il modo in cui il Docker-Opse.YML sembrerebbe.

Versione: '3'
Servizi:
mydb:
Immagine: Postgres
Volumi:
- DB-DATA:/var/lib/postgresql/dati
Porte:
- 5432: 5432
Volumi:
DB-DATA:
Driver: locale

L'ultima riga "Driver: Local" è completamente facoltativa ed è menzionata qui solo per dimostrare che il “Chiave di alto livello volumi " può avere più volumi definiti sotto di esso. DB-Data è uno di questi volumi che a sua volta ha dettagli, come i conducenti, incluso come un blocco rientrato sotto di esso.

Sotto il servizio MyDB abbiamo di nuovo la chiave di volumi. Questo "livello di servizio Tasto volumi " È solo un elenco di volumi definiti sotto il tasto dei volumi di livello superiore mappato sui punti di montaggio all'interno dei contenitori

Quando si esegue il comando up Docker-Op UP per la prima volta con la definizione YML sopra, creerà un volume, non con una stringa casuale come nome, ma db-bata come nome. Quindi in poi ogni volta che si abbassa l'applicazione (docker-compone verso il basso) e quindi eseguirà il riepilogo della compo-D-D-Dock-Op Up-D-D-DEUT di creare un volume chiamato DB-Data, ma si noterebbe che esiste già un volume con quel nome. Quindi tornerà a nuovo nello stesso volume. Abbattiamo l'applicazione per ora:

$ Docker-compone

Usando PostgreSQL

L'immagine ufficiale di Postgres espone la porta 5432 a nostro vantaggio. A rigor di termini, questo non è necessario. I database sono solo uno dei tanti servizi in esecuzione su una rete Docker. Gli altri servizi, come Web Server, possono parlare con il database senza che non sia pubblicata alcuna porta esplicita. Questo perché le reti di bridge definite dall'utente, come quelle che Docker compose crea da eseguire per le tue app, consentono ai contenitori dei membri di parlare liberamente tra loro. Quindi, se il server Web e il database si trovano sulla stessa rete di bridge, possono parlarsi tra loro anche senza che le porte vengano aperte esplicitamente.

I database spesso non sono esposti al mondo esterno, ma accessibili da altri servizi. Quindi, pubblicare la porta di Postgres non è qualcosa che vedresti spesso in produzione.

Tuttavia, sperimenteremo l'applicazione containerizzata per vedere se i dati effettivamente persistono in modo da poter esporre e pubblicare le porte per ora. Modifica la composizione Docker.File YML con opzione di porte aggiuntive.

Versione: '3'
Servizi:
mydb:
Immagine: Postgres
Volumi:
- DB-DATA:/var/lib/postgresql/dati
Porte:
- 5432: 5432/TC
Volumi:
DB-DATA:
Driver: locale

Ora siamo pronti a interfacciarci con l'istanza Postgres utilizzando il programma client PGADMIN. È possibile installare questo client sul tuo computer locale utilizzando il metodo preferito se segui questo link. Dopo aver installato il client, è possibile connettersi al server di database, ma prima iniziamo il server di database.

$ Docker -Opse Up -D

Questa volta le richieste in arrivo presso la porta host Docker 5432 verranno inoltrate alla porta 5432 del contenitore del database, dove Postgres Server può elaborarlo.

Connessione al server

Avvia il client PGadmin e puoi accedervi tramite il browser Web. Nella dashboard troverai l'opzione chiamata Aggiungi nuovo server.

Dagli un nome ragionevole, andiamo con "Il mio database ":

E sotto la scheda Connessioni Immettere l'indirizzo in cui il database è in esecuzione:

L'indirizzo può essere locale se stai eseguendo sia pgadmin che il contenitore postgres è in esecuzione sulla stessa macchina. Se si esegue il contenitore Postgres su un VPS remoto, ad esempio, l'indirizzo IP di quel VPS sarà necessario qui. In generale, lo chiamiamo indirizzo dell'host Docker perché è qui che è in esecuzione.

Lasceremo il campo password vuoto e anche il numero di porta predefinito 5432 va bene. Salva le impostazioni del server e creiamo un database.

In caso di connessione riuscita puoi vedere tutte le attività interne:

Dal menu del browser possiamo selezionare rapidamente Il mio database server e sotto di esso fai clic con il pulsante destro del mouse sul database e Crea un database.

Creiamo rapidamente un database chiamato Database di esempio.

Non devi creare nient'altro qui. Ora possiamo chiudere la finestra e tornare al terminal aperto nella stessa directory in cui il nostro docker si espone.YML vive.

$ Docker-compone
$ Docker -Opse Up -D

Il vecchio contenitore è ormai sparito e uno nuovo ha preso il suo posto. Puoi aprire di nuovo pgadmin e dovrai riconnetterti a questo database (farebbe una password vuota) e al suo interno scoprirai che tutto è come hai lasciato per essere. C'è anche un Database di esempio lì dentro.

Conclusione

Volevamo scrivere un file Docker-Opse che ha reso Postgres aggiornabile. Se arriva una nuova immagine di Postgres che esegue Postgres 11, ora puoi attirare con sicurezza la nuova immagine ed eseguire un aggiornamento senza preoccupazioni per lo stato dell'applicazione che si perde.

Il comportamento predefinito dell'immagine di Postgres che è creare un nuovo volume ogni volta che viene creato un contenitore non è una cattiva scelta di design. È implementato con i migliori interessi.

Ma rimane semplicemente un nuovo utente che si grafferebbe la testa chiedendosi dove si perdono tutti i dati e perché ci sono così tanti volumi che si schierano nel loro host Docker. Spero che non sia più un problema per i lettori.