El problema inicial
Tenía Grafana y Listmonk corriendo en contenedores Docker, cada uno con su propia instancia de PostgreSQL embebida. Esto funcionaba, pero era ineficiente: dos motores de BD consumiendo recursos y sin forma centralizada de hacer backups. Decidí consolidar todo en una única instancia PostgreSQL compartida.
Preparación: levantar PostgreSQL central
Lo primero fue crear el servidor PostgreSQL que seria el punto central. Lo hice con un docker-compose dedicado:
version: '3.8'
services:
postgres:
image: postgres:15-alpine
container_name: postgres-central
environment:
POSTGRES_USER: admin
POSTGRES_PASSWORD: tu_contraseña_segura
POSTGRES_DB: default_db
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- central-net
volumes:
postgres_data:
networks:
central-net:
driver: bridge
Ejecuté docker-compose up -d y verifiqué que funcionara con docker exec postgres-central psql -U admin -d default_db -c "\l".
Crear bases de datos para cada servicio
Accedí al contenedor PostgreSQL y creé las BD que necesitaría:
docker exec -it postgres-central psql -U admin -d default_db
Una vez dentro:
CREATE DATABASE grafana;
CREATE DATABASE listmonk;
CREATE USER grafana_user WITH PASSWORD 'grafana_pass';
CREATE USER listmonk_user WITH PASSWORD 'listmonk_pass';
GRANT ALL PRIVILEGES ON DATABASE grafana TO grafana_user;
GRANT ALL PRIVILEGES ON DATABASE listmonk TO listmonk_user;
Exportar datos de las BD antiguas
Antes de mover nada, hice un dump de las BD existentes. Para Grafana:
docker exec grafana-container pg_dump -U grafana -d grafana > grafana_backup.sql
Para Listmonk:
docker exec listmonk-container pg_dump -U listmonk -d listmonk > listmonk_backup.sql
Importar datos en PostgreSQL central
Importé los backups en las nuevas BD:
docker exec -i postgres-central psql -U grafana_user -d grafana < grafana_backup.sql
docker exec -i postgres-central psql -U listmonk_user -d listmonk < listmonk_backup.sql
Verifiqué que las tablas estuvieran presentes con \dt en cada BD.
Actualizar Grafana
Modifiqué el docker-compose de Grafana para que apunte a PostgreSQL central:
services:
grafana:
image: grafana/grafana:latest
container_name: grafana
environment:
GF_DATABASE_TYPE: postgres
GF_DATABASE_HOST: postgres-central:5432
GF_DATABASE_NAME: grafana
GF_DATABASE_USER: grafana_user
GF_DATABASE_PASSWORD: grafana_pass
networks:
- central-net
- grafana-net
networks:
central-net:
external: true
grafana-net:
driver: bridge
Importante: la red central-net debe ser external: true porque ya existe en el docker-compose de PostgreSQL.
Actualizar Listmonk
Lo mismo para Listmonk. Su config en docker-compose:
services:
listmonk:
image: listmonk/listmonk:latest
container_name: listmonk
environment:
LISTMONK_db__host: postgres-central
LISTMONK_db__port: "5432"
LISTMONK_db__user: listmonk_user
LISTMONK_db__password: listmonk_pass
LISTMONK_db__database: listmonk
networks:
- central-net
- listmonk-net
networks:
central-net:
external: true
listmonk-net:
driver: bridge
Testing y limpieza
Levanté ambos contenedores: docker-compose up -d. Verifiqué que Grafana y Listmonk iniciaran correctamente y que sus datos estuvieran intactos.
Una vez confirmado todo funcionaba, eliminé los volúmenes de las BD antiguas:
docker volume rm grafana_postgres_data listmonk_postgres_data
Beneficios reales
Ahora tengo un único punto de respaldo, menos consumo de RAM, y puedo escalar más fácilmente. Un problema: asegurate de que PostgreSQL central este en la red correcta o que los servicios puedan comunicarse por host externo.
La migración me tomó una hora. Sin estrés.
Equipamiento recomendado
- SSD NVMe 1TB — Mejora el rendimiento del servidor con base de datos
- Mini PC Intel N100 — Servidor doméstico silencioso y eficiente para correr Docker y PostgreSQL 24/7
- SAI/UPS 600VA — Protege el servidor y la base de datos de cortes de luz
Enlaces de afiliado. Sin coste extra para ti.