Introduzione
Docker ha modernizzato il modo in cui costruiamo e distribuiamo l'applicazione. Ci consente di creare contenitori leggeri, portatili e autosufficienti che possono eseguire facilmente qualsiasi applicazione.
Questo blog intendeva spiegare come utilizzare Docker per eseguire il database PostgreSQL. Non copre l'installazione o la configurazione della finestra mobile. Fare riferimento alle istruzioni di installazione della Docker qui. Ulteriori informazioni possono essere trovate nel nostro precedente blog su MySQL e Docker.
Prima di entrare nei dettagli, esaminiamo un po' di terminologia.
- File Docker
Contiene il set di istruzioni/comandi per installare o configurare l'applicazione/il software. - Immagine Docker
L'immagine Docker è costituita da una serie di livelli che rappresentano le istruzioni del Dockerfile. L'immagine Docker viene utilizzata come modello per creare un contenitore. - Collegamento di container e networking definito dall'utente
Docker utilizzava il bridge come meccanismo di rete predefinito e utilizzava --links per collegare i contenitori tra loro. Per accedere al contenitore PostgreSQL da un contenitore dell'applicazione, è necessario collegare entrambi i contenitori al momento della creazione. In questo articolo utilizziamo reti definite dall'utente poiché la funzione di collegamento sarà presto ritirata. - Persistenza dei dati in Docker
Per impostazione predefinita, i dati all'interno di un contenitore sono temporanei. Ogni volta che il contenitore viene riavviato, i dati andranno persi. I volumi sono il meccanismo preferito per rendere persistenti i dati generati e utilizzati da un container Docker. Qui stiamo montando una directory host all'interno del contenitore in cui sono archiviati tutti i dati.
Iniziamo a costruire la nostra immagine PostgreSQL e usiamola per eseguire un container.
File Docker PostgreSQL
# example Dockerfile for https://docs.docker.com/engine/examples/postgresql_service/
FROM ubuntu:14.04
# Add the PostgreSQL PGP key to verify their Debian packages.
# It should be the same key as https://www.postgresql.org/media/keys/ACCC4CF8.asc
RUN apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8
# Add PostgreSQL's repository. It contains the most recent stable release
# of PostgreSQL, ``9.3``.
RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ precise-pgdg main" > /etc/apt/sources.list.d/pgdg.list
# Install ``python-software-properties``, ``software-properties-common`` and PostgreSQL 9.3
# There are some warnings (in red) that show up during the build. You can hide
# them by prefixing each apt-get statement with DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y python-software-properties software-properties-common postgresql-9.3 postgresql-client-9.3 postgresql-contrib-9.3
# Note: The official Debian and Ubuntu images automatically ``apt-get clean``
# after each ``apt-get``
# Run the rest of the commands as the ``postgres`` user created by the ``postgres-9.3`` package when it was ``apt-get installed``
USER postgres
# Create a PostgreSQL role named ``postgresondocker`` with ``postgresondocker`` as the password and
# then create a database `postgresondocker` owned by the ``postgresondocker`` role.
# Note: here we use ``&&\`` to run commands one after the other - the ``\``
# allows the RUN command to span multiple lines.
RUN /etc/init.d/postgresql start &&\
psql --command "CREATE USER postgresondocker WITH SUPERUSER PASSWORD 'postgresondocker';" &&\
createdb -O postgresondocker postgresondocker
# Adjust PostgreSQL configuration so that remote connections to the
# database are possible.
RUN echo "host all all 0.0.0.0/0 md5" >> /etc/postgresql/9.3/main/pg_hba.conf
# And add ``listen_addresses`` to ``/etc/postgresql/9.3/main/postgresql.conf``
RUN echo "listen_addresses='*'" >> /etc/postgresql/9.3/main/postgresql.conf
# Expose the PostgreSQL port
EXPOSE 5432
# Add VOLUMEs to allow backup of config, logs and databases
VOLUME ["/etc/postgresql", "/var/log/postgresql", "/var/lib/postgresql"]
# Set the default command to run when starting the container
CMD ["/usr/lib/postgresql/9.3/bin/postgres", "-D", "/var/lib/postgresql/9.3/main", "-c", "config_file=/etc/postgresql/9.3/main/postgresql.conf"]
Se osservi il Dockerfile da vicino, è costituito da comandi che vengono utilizzati per installare PostgreSQL ed eseguire alcune modifiche alla configurazione sul sistema operativo Ubuntu.
Creazione di un'immagine PostgreSQL
Possiamo creare un'immagine PostgreSQL da Dockerfile usando il comando docker build.
# sudo docker build -t postgresondocker:9.3 .
Qui possiamo specificare il tag (-t) per l'immagine come nome e versione. Il punto (.) alla fine specifica la directory corrente e utilizza il Dockerfile presente nella directory corrente. Il nome del file Docker dovrebbe essere "Dockerfile". Se vuoi specificare un nome personalizzato per il tuo file docker, dovresti usare -f
# sudo docker build -t postgresondocker:9.3 -f <your_docker_file_name>
Output:(se possibile, utilizzare la finestra di testo della barra di scorrimento)
Sending build context to Docker daemon 4.096kB
Step 1/11 : FROM ubuntu:14.04
14.04: Pulling from library/ubuntu
324d088ce065: Pull complete
2ab951b6c615: Pull complete
9b01635313e2: Pull complete
04510b914a6c: Pull complete
83ab617df7b4: Pull complete
Digest: sha256:b8855dc848e2622653ab557d1ce2f4c34218a9380cceaa51ced85c5f3c8eb201
Status: Downloaded newer image for ubuntu:14.04
---> 8cef1fa16c77
Step 2/11 : RUN apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8
---> Running in ba933d07e226
.
.
.
fixing permissions on existing directory /var/lib/postgresql/9.3/main ... ok
creating subdirectories ... ok
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
creating configuration files ... ok
creating template1 database in /var/lib/postgresql/9.3/main/base/1 ... ok
initializing pg_authid ... ok
initializing dependencies ... ok
creating system views ... ok
loading system objects' descriptions ... ok
creating collations ... ok
creating conversions ... ok
creating dictionaries ... ok
setting privileges on built-in objects ... ok
creating information schema ... ok
loading PL/pgSQL server-side language ... ok
vacuuming database template1 ... ok
copying template1 to template0 ... ok
copying template1 to postgres ... ok
syncing data to disk ... ok
Success. You can now start the database server using:
/usr/lib/postgresql/9.3/bin/postgres -D /var/lib/postgresql/9.3/main
or
/usr/lib/postgresql/9.3/bin/pg_ctl -D /var/lib/postgresql/9.3/main -l logfile start
Ver Cluster Port Status Owner Data directory Log file
9.3 main 5432 down postgres /var/lib/postgresql/9.3/main /var/log/postgresql/postgresql-9.3-main.log
update-alternatives: using /usr/share/postgresql/9.3/man/man1/postmaster.1.gz to provide /usr/share/man/man1/postmaster.1.gz (postmaster.1.gz) in auto mode
invoke-rc.d: policy-rc.d denied execution of start.
Setting up postgresql-contrib-9.3 (9.3.22-0ubuntu0.14.04) ...
Setting up python-software-properties (0.92.37.8) ...
Setting up python3-software-properties (0.92.37.8) ...
Setting up software-properties-common (0.92.37.8) ...
Processing triggers for libc-bin (2.19-0ubuntu6.14) ...
Processing triggers for ca-certificates (20170717~14.04.1) ...
Updating certificates in /etc/ssl/certs... 148 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d....done.
Processing triggers for sgml-base (1.26+nmu4ubuntu1) ...
Removing intermediate container fce692f180bf
---> 9690b681044b
Step 5/11 : USER postgres
---> Running in ff8864c1147d
Removing intermediate container ff8864c1147d
---> 1f669efeadfa
Step 6/11 : RUN /etc/init.d/postgresql start && psql --command "CREATE USER postgresondocker WITH SUPERUSER PASSWORD 'postgresondocker';" && createdb -O postgresondocker postgresondocker
---> Running in 79042024b5e8
* Starting PostgreSQL 9.3 database server
...done.
CREATE ROLE
Removing intermediate container 79042024b5e8
---> 70c43a9dd5ab
Step 7/11 : RUN echo "host all all 0.0.0.0/0 md5" >> /etc/postgresql/9.3/main/pg_hba.conf
---> Running in c4d03857cdb9
Removing intermediate container c4d03857cdb9
---> 0cc2ed249aab
Step 8/11 : RUN echo "listen_addresses='*'" >> /etc/postgresql/9.3/main/postgresql.conf
---> Running in fde0f721c846
Removing intermediate container fde0f721c846
---> 78263aef9a56
Step 9/11 : EXPOSE 5432
---> Running in a765f854a274
Removing intermediate container a765f854a274
---> d205f9208162
Step 10/11 : VOLUME ["/etc/postgresql", "/var/log/postgresql", "/var/lib/postgresql"]
---> Running in ae0b9f30f3d0
Removing intermediate container ae0b9f30f3d0
---> 0de941f8687c
Step 11/11 : CMD ["/usr/lib/postgresql/9.3/bin/postgres", "-D", "/var/lib/postgresql/9.3/main", "-c", "config_file=/etc/postgresql/9.3/main/postgresql.conf"]
---> Running in 976d283ea64c
Removing intermediate container 976d283ea64c
---> 253ee676278f
Successfully built 253ee676278f
Successfully tagged postgresondocker:9.3
Creazione di una rete di container
Utilizzare il comando seguente per creare una rete definita dall'utente con driver bridge.
# sudo docker network create --driver bridge postgres-network
Conferma creazione rete
# sudo docker network ls
NETWORK ID NAME DRIVER SCOPE
a553e5727617 bridge bridge local
0c6e40305851 host host local
4cca2679d3c0 none null local
83b23e0af641 postgres-network bridge local
Creazione del contenitore
È necessario utilizzare il comando "docker run" per creare un contenitore dall'immagine della finestra mobile. Stiamo eseguendo il contenitore postgres in modalità demone con l'aiuto dell'opzione -d.
# sudo docker run --name postgresondocker --network postgres-network -d postgresondocker:9.3
Utilizza il comando seguente per confermare la creazione del contenitore.
# sudo docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
06a5125f5e11 postgresondocker:9.3 "/usr/lib/postgresql…" About a minute ago Up About a minute 5432/tcp postgresondocker
Non abbiamo specificato alcuna porta da esporre, quindi esporrà la porta postgres predefinita 5432 per uso interno. PostgreSQL è disponibile solo dall'interno della rete Docker, non saremo in grado di accedere a questo container Postgres su una porta host.
Vedremo come accedere al container Postgres sulla porta host in una sezione successiva di questo articolo.
Connessione al container PostgreSQL all'interno della rete Docker
Proviamo a connetterci al container Postgres da un altro container all'interno della stessa rete Docker che abbiamo creato in precedenza. Qui, abbiamo usato il client psql per connetterci a Postgres. Abbiamo utilizzato il nome del contenitore Postgres come nome host, utente e password presenti nel file Docker.
# docker run -it --rm --network postgres-network postgresondocker:9.3 psql -h postgresondocker -U postgresondocker --password
Password for user postgresondocker:
psql (9.3.22)
SSL connection (cipher: DHE-RSA-AES256-GCM-SHA384, bits: 256)
Type "help" for help.
postgresondocker=#
L'opzione --rm nel comando run rimuoverà il contenitore una volta terminato il processo psql.
# sudo docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2fd91685d1ea postgresondocker:9.3 "psql -h postgresond…" 29 seconds ago Up 30 seconds 5432/tcp brave_spence
06a5125f5e11 postgresondocker:9.3 "/usr/lib/postgresql…" About a minute ago Up About a minute 5432/tcp postgresondocker
Persistenza dei dati
I container Docker sono di natura effimera, ad es. i dati utilizzati o generati dal container non vengono archiviati da nessuna parte in modo implicito. Perdiamo i dati ogni volta che il contenitore viene riavviato o eliminato. Docker fornisce volumi su cui possiamo archiviare i dati persistenti. È una funzione utile grazie alla quale possiamo effettuare il provisioning di un altro container utilizzando lo stesso volume o dati in caso di emergenza.
Creiamo un volume di dati e confermiamo la sua creazione.
# sudo docker volume create pgdata
pgdata
# sudo docker volume ls
DRIVER VOLUME NAME
local pgdata
Ora dobbiamo utilizzare questo volume di dati durante l'esecuzione del contenitore Postgres. Assicurati di eliminare il vecchio container Postgres che è in esecuzione senza volumi.
# sudo docker container rm postgresondocker -f
postgresondocker
# sudo docker run --name postgresondocker --network postgres-network -v pgdata:/var/lib/postgresql/9.3/main -d postgresondocker:9.3
Abbiamo eseguito il container Postgres con un volume di dati allegato.
Crea una nuova tabella in Postgres per verificare la persistenza dei dati.
# docker run -it --rm --network postgres-network postgresondocker:9.3 psql -h postgresondocker -U postgresondocker --password
Password for user postgresondocker:
psql (9.3.22)
SSL connection (cipher: DHE-RSA-AES256-GCM-SHA384, bits: 256)
Type "help" for help.
postgresondocker=# \dt
No relations found.
postgresondocker=# create table test(id int);
CREATE TABLE
postgresondocker=# \dt
List of relations
Schema | Name | Type | Owner
--------+------+-------+------------------
public | test | table | postgresondocker
(1 row)
Elimina il contenitore Postgres.
# sudo docker container rm postgresondocker -f
postgresondocker
Crea un nuovo contenitore Postgres e conferma la tabella di test presente o meno.
# sudo docker run --name postgresondocker --network postgres-network -v pgdata:/var/lib/postgresql/9.3/main -d postgresondocker:9.3
# docker run -it --rm --network postgres-network postgresondocker:9.3 psql -h postgresondocker -U postgresondocker --password
Password for user postgresondocker:
psql (9.3.22)
SSL connection (cipher: DHE-RSA-AES256-GCM-SHA384, bits: 256)
Type "help" for help.
postgresondocker=# \dt
List of relations
Schema | Name | Type | Owner
--------+------+-------+------------------
public | test | table | postgresondocker
(1 row)
Scarica il whitepaper oggi Gestione e automazione di PostgreSQL con ClusterControlScopri cosa devi sapere per distribuire, monitorare, gestire e ridimensionare PostgreSQLScarica il whitepaper Esponi il servizio PostgreSQL all'host
Potresti aver notato che non abbiamo esposto in precedenza alcuna porta del contenitore PostgreSQL. Ciò significa che PostgreSQL è accessibile solo ai contenitori che si trovano nella rete postgres che abbiamo creato in precedenza.
Per utilizzare il servizio PostgreSQL, dobbiamo esporre la porta del contenitore usando l'opzione --port. Qui abbiamo esposto la porta del container Postgres 5432 sulla porta 5432 dell'host.
# sudo docker run --name postgresondocker --network postgres-network -v pgdata:/var/lib/postgresql/9.3/main -p 5432:5432 -d postgresondocker:9.3
# sudo docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
997580c86188 postgresondocker:9.3 "/usr/lib/postgresql…" 8 seconds ago Up 10 seconds 0.0.0.0:5432->5432/tcp postgresondocker
Ora puoi connettere PostgreSQL direttamente su localhost.
# psql -h localhost -U postgresondocker --password
Password for user postgresondocker:
psql (9.3.22)
SSL connection (cipher: DHE-RSA-AES256-GCM-SHA384, bits: 256)
Type "help" for help.
postgresondocker=#
Eliminazione contenitore
Per eliminare il contenitore, dobbiamo prima arrestare il contenitore in esecuzione e quindi eliminare il contenitore utilizzando il comando rm.
# sudo docker container stop postgresondocker
# sudo docker container rm postgresondocker
postgresondocker
Usa l'opzione -f (--force) per eliminare direttamente il contenitore in esecuzione.
# sudo docker container rm postgresondocker -f
postgresondocker
Si spera che ora tu abbia il tuo ambiente locale ancorato per PostgreSQL.
Nota: Questo articolo fornisce una panoramica su come utilizzare PostgreSQL nella finestra mobile per l'ambiente di sviluppo/POC. L'esecuzione di PostgreSQL nell'ambiente di produzione potrebbe richiedere ulteriori modifiche alle configurazioni di PostgreSQL o della finestra mobile.
Conclusione
Esiste un modo semplice per eseguire il database PostgreSQL all'interno di un contenitore Docker. Docker incapsula efficacemente la distribuzione, la configurazione e alcune procedure di amministrazione. Docker è una buona scelta per distribuire PostgreSQL con il minimo sforzo. Tutto quello che devi fare è avviare un container Docker pre-costruito e avrai il database PostgreSQL pronto per il tuo servizio.
Riferimenti
- Installazione Docker:https://docs.docker.com/install
- Volumi:https://docs.docker.com/storage/volumes
- Reti definite dall'utente:https://docs.docker.com/network/
- File Docker Postgres:https://docs.docker.com/engine/examples/postgresql_service
- MySQL su Docker:comprensione delle basi:https://diversealnines.com/blog/mysql-docker-containers-understanding-basics