Bases de datos en contendores – PostgreSQL

Tenía ganas de volver a escribir sobre la serie Bases de datos en contenedores que comenzó hace unos meses, creo que puede ser de mucha utilidad para todos aquellos que quieren trabajar o experimentar con bases de datos en sus equipos, de forma rápida y sin complicaciones. Hoy vamos a tratar con PostgreSQL en entorno Linux, y vamos a añadir algunos ingredientes más a la receta…

Objetivo

Nuestro objetivo es poder trabajar con un servidor de PostgreSQL en local, y contar con una interfaz gráfica para  administración, pgAdmin. Además, nos marcamos los siguientes requisitos para la configuración de este entorno de trabajo:

  1. Que sea fácil.
  2. Que sear portable.
  3. Que sea rápido.

¡Manos a la obra!

Prerequisitos

Necesitaremos las siguientes herramientas instaladas:

Comentar que la distribución linux que utilizo para esta guía es CentOS 7, por lo que los comandos a continuación son pensando en este escenario.

Instalando Docker

# Instalando Docker en Centos 7 via Docker Repository
# Instalando paquetes necesarios
sudo yum install -y yum-utils \
 device-mapper-persistent-data \
 lvm2

# Añadiendo el repositorio de docker-ce
sudo yum-config-manager \
 --add-repo \
 https://download.docker.com/linux/centos/docker-ce.repo

# Instalamos docker
sudo yum install docker-ce

# Validamos la instalación con el comando version
docker --version

# Iniciamos el docker deamon
sudo systemctl start docker

# Ejecutamos un contenedor de pruebas
sudo docker run hello-world

# Añadimos nuestro usuario al grupo de docker
sudo usermod -aG docker $USER

Cerramos nuestra sesión y volvemos a iniciarla para que se aplique el cambio de grupo. También podemos hacer lo siguiente:

sudo pkill -u $USER

# Comprobamos que ya no necesitamos hacer sudo para ejecutar docker
docker run hello-world

# Configuramos docker para que se ejecute al iniciar 
sudo systemctl enable docker

Hay más opciones para la instalación, puedes encontrarlo en: https://docs.docker.com/engine/install/centos/

Instalando Docker Compose

# Instalamos docker-compose
sudo curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# Añadimos el permiso de ejecución al docker-compose
sudo chmod +x /usr/local/bin/docker-compose

# Validamos la instalación de docker-compose
docker-compose --version

Hay más opciones para la instalación, puedes encontrarlo en: https://docs.docker.com/compose/install/

Proceso manual

Creo que a nadie le puede gustar hacer las cosas manualmente una y otra vez. Sin embargo, creo que es básico conocer el proceso existente antes de automatizarlo. Antes de correr, hay que saber andar.

1) Crear el contenedor para PostgreSQL

# Creamos una ruta de trabajo para postgreSQL
cd $HOME/docker
mkdir pgdev
cd pgdev

# Descargamos la imagen del contenedor de PostgreSQL desde repositorio oficial
docker pull postgres

Si nos interesara una versión específica entonces usaremos: postgres:[tag_version]. Puedes ver las versiones disponibles en docker hub: https://hub.docker.com/_/postgres

postgres 
Updated 15 hours aso 
The PostgreSQL object-relational database system provides reliability and data integrity. 
Container Linux ARM64 386 ARM IBM Z x86-64 mips641e 
OFFICIAL IMAGE Q 
IOM+ 9.0K 
Downloads Stars 
Databases
# Creamos una red: red-pg
docker network create red-pg

# Creamos un volumen para persistir los datos
# Creamos la ruta en nuestra máquina que usaremos para mapear la ruta de datos del contenedor
mkdir -p ~/docker/volumes/datos-pg

# Creamos el contenedor con PostgreSQL
docker run --rm  --name postgresql \
  -e POSTGRES_PASSWORD=docker \
  -p 5432:5432 \
  -v $HOME/docker/volumes/datos-pg:/var/lib/postgresql/data \
  --shm-size=256MB \
  --network red-pg \
  -d postgres

Explicación del comando anterior parámetro a parámetro: 

–rmBorra de forma automática el contenedor en caso de que exista
–nameEn vez de dejar que el docker engine le ponga un nombre arbitrario, le especificamos uno
-ePara pasar las variables de entorno. Esto dependerá de cada contenedor. Para nuestro caso sólo especificamos la contraseña del administrador (postgres). Puedes encontrar más variables en https://hub.docker.com/_/postgres (Environment Variables)
-pMapeo de puertos. Puerto en el host:Puerto en el contenedor
-vMapeo de volúmenes de almacenamiento. Volumen en el host:Volumen en el contenedor
–shm-size=256MBLa memoria compartida /dev/shm tiene un tamaño por defecto de 64MB. Si la memoria compartida se queda exausta, encontrarás el siguiente mensaje: ERROR: could not resize shared memory segment . . . : No space left on device. Se recomienda usar un tamaño más adecuado
–networkEspecificamos la red a la que el contenedor va a tener acceso
-dEjecuta el contenedor en segundo plano, o background
# Comprobar el estado del contenedor de postgreSQL
docker ps -a
docker logs postgresql

Ahora podemos por ejemplo conectarnos con un cliente sql, como dbeaver, desde nuestra máquina o host. Tan sólo nos hará falta introducir la misma contraseña que usamos en el comando docker run anterior:

Database Navigator Projects 
Enter a part of table name here 
v postgres 
v postgres 
v Schemas 
[i] information_schema 
pg_catalog 
public 
> Roles 
23 Administer 
23 Extensions 
Storage 
System Info 
File 
3 
D8eaver 73.5- Script 
Edit Navigate Search SQL Editor Database 
e ee*IIJsQL 
Commit 
Window Help 
Rollback 
Auto 
Script 
SELECT feature id, feature name, sub ff 
FROM information_schema . sql_features; 
sql_featuresl 
OT SELECT feature_id, feature_name, sub_feature_id, sub_feat 
eature 
8011 
8012 
8013 
8014 
8015 
8016 
8017 
feature name 
Embedded Ada 
Embedded C 
Embedded COBOL 
Embedded Fortran 
Embedded MUMPS 
Embedded Pascal 
Embedded PL/1

2) Crear el contenedor para pgAdmin

# Descargamos la imagen del contenedor de pgadmin4 del docker hub
docker pull dpage/pgadmin4

# Creamos un volumen para persistir los datos de pgadmin
# Creamos la ruta en nuestra máquina que usaremos para mapear la ruta de datos del contenedor
mkdir -p ~/docker/volumes/pgadmin4
cd ~/docker/volumes/
sudo chown -R 5050:5050 pgadmin4

Explicación: pgadmin es ejecutado por el usuario pgadmin (UID: 5050) en el grupo pgadmin (GID:5050), hay que asegurar que este usuario tenga permisos en la ruta creada.

# Creamos el contenedor con pgadmin
docker run --rm  --name pgadmin \
  -e "PGADMIN_DEFAULT_EMAIL=mando@mandalore.sw" \
  -e "PGADMIN_DEFAULT_PASSWORD=grogu" \
  -e "PGADMIN_LISTEN_PORT=80" \
  -p 8080:80 \
  -v $HOME/docker/volumes/pgadmin4:/var/lib/pgadmin \
  --network red-pg \
  -d dpage/pgadmin4

El comando docker run es muy parecido al anterior para postgresql, la principal diferencia está en las variables de entorno. Puedes ver más sobre las variables de pgadmin en: https://www.pgadmin.org/docs/pgadmin4/development/container_deployment.html

Una vez ejecutado, esperamos a que el servicio web de pgadmin esté arriba:

docker logs -f pgadmin

Y desde nuestro host, tan sólo tenemos que abrir el navegador e introducir la ip y el puerto 8080 que se especificó en el docker run anterior:

Introducimos las credenciales que pusimos en la variables de entorno del último docker run. Luego configuramos el acceso al servidor de postgresql con sus credenciales y…¡Tenemos pgAdmin!

Si tienes curiosidad sobre pgAdmin, aquí puedes encontrar un montón de documentación, videos y guías: https://www.pgadmin.org/

Automatización

Ya hemos visto el proceso manual, a continuación vamos a ver cómo podemos lograr lo mismo pero de forma automática. Esto require una preparación que vamos a ver:

1) Creamos un fichero docker-compose.yaml

cd $HOME/docker/pgdev
vi docker-compose.yaml

Con el siguiente contenido:

version: "3.7"
services:
  db:
    image: postgres
    restart: always
    environment:
      POSTGRES_DB: postgres
      POSTGRES_PASSWORD: secret
      PGDATA: /var/lib/postgresql/data
    volumes:
      - $HOME/docker/volumes/datos-pg:/var/lib/postgresql/data
    ports:
      - "5432:5432"

  pgadmin:
    image: dpage/pgadmin4
    restart: always
    environment:
      PGADMIN_DEFAULT_EMAIL: mando@mandalore.sw
      PGADMIN_DEFAULT_PASSWORD: grogu
      PGADMIN_LISTEN_PORT: 80
    ports:
      - "8080:80"
    volumes:
      - $HOME/docker/volumes/pgadmin4:/var/lib/pgadmin

Ten en cuenta que si nos saltamos el proceso manual, habrá que crear las rutas que usamos en volumes, y dar los permisos en la carpeta de pgadmin4 que está detallado en el proceso manual.

2) Fase de prueba

Comprobamos que docker compose pueda levantar los dos contenedores:

docker-compose up -d
 Creating network "pgdev_default" with the default driver
 Creating pgdev_db_1      ... done
 Creating pgdev_pgadmin_1 ... done

docker-compose ps
     Name                    Command              State               Ports
---------------------------------------------------------------------------------------
pgdev_db_1        docker-entrypoint.sh postgres   Up      0.0.0.0:5432->5432/tcp
pgdev_pgadmin_1   /entrypoint.sh                  Up      443/tcp, 0.0.0.0:8080->80/tcp

Podemos ver que los dos contenedores  están arriba con sus servicios escuchando en sus respectivos puertos.Volvemos a comprobar que tanto dbeaver como pgAdmin pueden conectarse como vimos anteriormente. Cuando queramos terminar sólo tenemos que usar el siguiente comando:

docker-compose down

Proceso automatizado

cd $HOME/docker/pgdev
docker-compose up -d

Teniendo preparado el archivo docker-compose.yaml, nos basta con ejecutar el comando de docker-compose para tener PostgreSQL como base de datos y pgAdmin como complemento para administrarlo. Para hacer todas las pruebas que necesitemos en nuestro local.

Conclusión

Gracias a docker-compose hemos logrado nuestro objetivo, que era poder trabajar con un servidor de PostgreSQL, y contar con una interfaz gráfica para su administración. Hemos repasado las herramientas que necesitabamos, repasado el proceso manual usando sólo docker, y finalmente lo hemos automatizado de forma que hemos reducido a UN solo comando ¡Simple y eficaz!

¡Hasta el próximo artículo!

Deja una respuesta

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Salir /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Salir /  Cambiar )

Conectando a %s