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:
- Que sea fácil.
- Que sear portable.
- 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

# 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:
–rm | Borra de forma automática el contenedor en caso de que exista |
–name | En vez de dejar que el docker engine le ponga un nombre arbitrario, le especificamos uno |
-e | Para 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) |
-p | Mapeo de puertos. Puerto en el host:Puerto en el contenedor |
-v | Mapeo de volúmenes de almacenamiento. Volumen en el host:Volumen en el contenedor |
–shm-size=256MB | La 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 |
–network | Especificamos la red a la que el contenedor va a tener acceso |
-d | Ejecuta 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](https://bonisql.files.wordpress.com/2021/02/image-1.png?w=640)
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!