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: bridgeEjecuté 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_dbUna 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.sqlPara Listmonk:
docker exec listmonk-container pg_dump -U listmonk -d listmonk > listmonk_backup.sqlImportar 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.sqlVerifiqué 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: bridgeImportante: 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: bridgeTesting 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_dataBeneficios 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.