DEV Community

Cover image for Estrategias de respaldo y recuperación de PostgreSQL con Docker, Render y GitHub Actions

Estrategias de respaldo y recuperación de PostgreSQL con Docker, Render y GitHub Actions

Autor: Yerry Maycol Tarqui Collatupa

Curso: Base de Datos II — Universidad Privada de Tacna

Trabajo: Database Backup Strategies

En este artículo documentamos la construcción, automatización y validación de estrategias de respaldo y recuperación de PostgreSQL, desde un entorno local con Docker hasta Render y GitHub Actions.

Introducción

La pérdida de información puede comprometer la continuidad de una aplicación incluso cuando el código fuente se encuentra correctamente versionado. En un sistema que depende de una base de datos, disponer de una copia de seguridad no es suficiente por sí solo: también es necesario comprobar que el archivo generado puede restaurarse, definir dónde se conservará y reducir la cantidad de tareas manuales necesarias para producir nuevas copias.

A partir de este problema desarrollamos Database Backup Strategies, un proyecto práctico orientado a implementar y validar estrategias de respaldo y recuperación de PostgreSQL. El trabajo integra Docker y Docker Compose para el entorno local, PowerShell para la generación de copias, FastAPI para exponer los datos, GitHub para el control de versiones, Render para el despliegue en la nube y GitHub Actions para automatizar respaldos remotos cifrados.

La implementación se construyó de forma progresiva. Primero preparamos PostgreSQL y datos de prueba; después generamos respaldos locales, automatizamos su ejecución y demostramos su recuperación. Sobre esa base publicamos una API en Render, verificamos el despliegue automático desde GitHub y finalmente automatizamos también el respaldo de PostgreSQL en la nube. Esta publicación documenta las evidencias principales del trabajo sin convertir el artículo en una simple sucesión de capturas.

Arquitectura de la solución

La solución se diseñó con dos entornos complementarios. En local, Docker Compose ejecuta PostgreSQL y FastAPI; PowerShell invoca pg_dump y el Programador de tareas de Windows permite programar las copias. En la nube, Render aloja PostgreSQL y la API, mientras que GitHub mantiene el código y activa el despliegue del servicio cuando se actualiza la rama principal.

Diagrama del flujo de backup automático de PostgreSQL en Render mediante GitHub Actions y almacenamiento privadoFigura 1. Flujo de respaldo automático de PostgreSQL en Render mediante GitHub Actions y almacenamiento privado.

Para separar el código de las copias de seguridad utilizamos dos repositorios. El proyecto principal es público y contiene únicamente los archivos necesarios para reproducir la aplicación. Los respaldos remotos, en cambio, se conservan cifrados en un repositorio privado independiente. De esta manera, la solución diferencia con claridad el código fuente, la infraestructura de ejecución y los archivos de recuperación.

Preparación del entorno local

Comenzamos verificando Docker y Docker Compose en el equipo de desarrollo. Esta comprobación permitió asegurar que el entorno podía crear contenedores, construir imágenes y administrar los servicios requeridos para PostgreSQL y la aplicación web.

Verificación del entorno Docker antes de iniciar la implementaciónFigura 2. Comprobación del entorno de Docker antes de iniciar la implementación.

PostgreSQL se configuró con Docker Compose sobre una imagen de la versión 16. Las credenciales y el nombre de la base se definieron mediante variables de entorno, mientras que un volumen persistente se encargó de conservar los datos del motor fuera del ciclo de vida del contenedor. Las credenciales reales se mantuvieron excluidas del repositorio mediante .gitignore.

Con el servicio activo comprobamos la conexión y ejecutamos un script SQL para crear la tabla productos. Como conjunto de validación insertamos tres registros claramente identificables: Laptop Lenovo, Mouse Logitech y Teclado mecánico. Estos mismos registros se utilizaron posteriormente para comprobar tanto la API como las restauraciones.

Consulta de los tres productos registrados en PostgreSQLFigura 3. Datos de prueba almacenados en la tabla productos de PostgreSQL.

Generación del backup local

El primer mecanismo de respaldo se implementó mediante un script PowerShell denominado backup.ps1. El script genera un nombre de archivo basado en fecha y hora, ejecuta pg_dump dentro del contenedor, copia el resultado a la carpeta local backups y comprueba que el archivo resultante tenga contenido. Esta verificación evita considerar como válido un archivo vacío o una ejecución interrumpida.

Script PowerShell para generar backups locales mediante pg_dumpFigura 4. Script PowerShell utilizado para generar el respaldo local con pg_dump.

Antes de automatizar el proceso ejecutamos el script manualmente. La prueba generó correctamente un archivo en formato personalizado de PostgreSQL, lo que confirmó que las variables, el contenedor y la ruta de almacenamiento estaban configurados de manera coherente.

Primera ejecución satisfactoria del backup local de PostgreSQLFigura 5. Primera ejecución satisfactoria del backup local.

Automatización local

Una vez validado el script configuramos el Programador de tareas de Windows para ejecutarlo sin intervención manual. Durante la prueba se estableció una repetición cada cinco minutos durante una hora. Este intervalo corto se utilizó únicamente para demostrar varias ejecuciones dentro del tiempo de validación; en un escenario productivo la frecuencia debe definirse de acuerdo con las necesidades de recuperación del sistema.

Configuración del Programador de tareas de Windows para automatizar los backupsFigura 6. Desencadenador configurado para repetir el backup cada cinco minutos durante la prueba.

El resultado se comprobó observando el historial de la tarea y la creación sucesiva de archivos .dump con marcas de tiempo diferentes. Con ello demostramos que el respaldo local no dependía de ejecutar manualmente backup.ps1 en cada ocasión.

Ejecución automática y generación sucesiva de respaldos localesFigura 7. Ejecución programada y aparición sucesiva de respaldos locales.

Restauración y validación

La generación de una copia no se dio por válida hasta comprobar su recuperación. Seleccionamos el respaldo más reciente, lo copiamos al contenedor y utilizamos pg_restore para inspeccionar su contenido. La lista mostró los objetos asociados a la tabla productos, incluidas su secuencia, restricciones y datos.

Copia del archivo de respaldo al contenedor PostgreSQL para su recuperaciónFigura 8. Inspección del contenido del respaldo mediante pg_restore.

Posteriormente creamos una base de datos independiente destinada únicamente a la restauración. Ejecutamos pg_restore sobre ella y consultamos nuevamente productos. Los tres registros originales aparecieron con sus valores de precio y stock, confirmando que la copia podía utilizarse para recuperar la información sin alterar la base de datos principal.

Restauración de PostgreSQL y recuperación de los tres productos originalesFigura 9. Restauración local completada y recuperación de los tres productos.

Aplicación FastAPI

Para disponer de una comprobación funcional sobre los datos construimos una API REST con FastAPI. La aplicación obtiene la cadena de conexión desde DATABASE_URL y expone tres rutas principales: la raíz para informar el estado de la aplicación, /health para validar PostgreSQL y /productos para consultar los registros almacenados.

Implementación de los endpoints principales de la API con FastAPIFigura 10. Implementación de los endpoints principales de FastAPI.

La API se incorporó a Docker Compose y se ejecutó junto con PostgreSQL. Finalmente utilizamos la documentación Swagger de FastAPI para invocar GET /productos. La respuesta HTTP 200 mostró exactamente los mismos tres registros utilizados en las pruebas de restauración.

Validación del endpoint productos mediante Swagger con respuesta HTTP 200Figura 11. Respuesta HTTP 200 de GET /productos desde Swagger.

Repositorio público

Antes de publicar el proyecto protegimos los archivos sensibles. El archivo .gitignore excluyó variables de entorno, copias .dump, evidencias locales y otros archivos que no debían formar parte del repositorio. Para facilitar la configuración posterior se mantuvo una plantilla .env.example sin utilizar el archivo .env real.

Configuración de gitignore para proteger credenciales y archivos sensiblesFigura 12. Reglas de exclusión empleadas antes de publicar el proyecto.

Después inicializamos Git, realizamos el primer commit y creamos un repositorio público. El resultado deja disponibles el código de FastAPI, Dockerfile, Docker Compose, el script SQL y backup.ps1, manteniendo fuera de Git las credenciales y los respaldos generados.

Repositorio público Database Backup Strategies alojado en GitHubFigura 13. Repositorio público del proyecto Database Backup Strategies.

Publicación en la nube

El siguiente objetivo fue ejecutar la solución fuera del equipo local. Creamos el proyecto en Render y posteriormente una instancia de PostgreSQL asociada al entorno de producción. La base quedó disponible y preparada para ser utilizada por el servicio web.

Configuración de la instancia PostgreSQL en la plataforma RenderFigura 14. Configuración de recursos para la instancia PostgreSQL en Render.

FastAPI se desplegó como Web Service conectado al repositorio de GitHub. La configuración utilizó Docker y la variable DATABASE_URL para enlazar la aplicación con PostgreSQL en Render. Una vez finalizado el despliegue, el servicio quedó accesible mediante una URL pública.

Despliegue de la aplicación FastAPI mediante RenderFigura 15. Despliegue inicial de FastAPI completado correctamente en Render.

Después cargamos los datos de prueba en la base remota y repetimos las verificaciones realizadas en local. El endpoint público /productos devolvió los tres registros, demostrando que la aplicación estaba utilizando PostgreSQL en Render y no la base local.

Consulta pública de los productos almacenados en PostgreSQL de RenderFigura 16. Consulta pública de /productos utilizando PostgreSQL alojado en Render.

Despliegue automatizado

Para demostrar el despliegue automatizado verificamos que Render estuviera configurado para actualizar el servicio a partir de cambios en la rama principal del repositorio. Modificamos el endpoint inicial de FastAPI para incorporar la versión 1.0.1 y el texto que identifica el despliegue desde GitHub.

El cambio se registró mediante commit y se envió con git push a main. A partir de ese envío, Render detectó la nueva revisión y generó un nuevo despliegue sin que tuviéramos que reconstruir manualmente el servicio desde el panel.

Despliegue automático de la aplicación desde GitHub hacia RenderFigura 17. Registro del despliegue automático en Render activado desde GitHub.

Al finalizar, la URL pública mostró la versión 1.0.1 y el indicador de despliegue automatizado. Esta prueba permitió diferenciar claramente el despliegue automático de la automatización de backups: el primero publica nuevas versiones de la aplicación y el segundo genera copias de la base de datos.

Verificación de la versión 1.0.1 publicada automáticamente en RenderFigura 18. Versión 1.0.1 publicada automáticamente en Render después del push.

Backup de PostgreSQL de Render

Con la aplicación ya publicada comprobamos también la recuperación de los datos de la nube. Para ello utilizamos temporalmente la External Database URL de Render sin exponerla en las capturas. Mediante pg_dump generamos una copia completa de PostgreSQL remoto en formato personalizado y verificamos su contenido con pg_restore.

Generación del backup de PostgreSQL alojado en RenderFigura 19. Generación e inspección del backup de PostgreSQL alojado en Render.

El archivo se copió desde el contenedor hacia Windows con un nombre que incorpora fecha y hora. Después lo introdujimos nuevamente en el contenedor y lo restauramos sobre una base de datos local de prueba. La ejecución terminó con código 0 y la consulta final recuperó Laptop Lenovo, Mouse Logitech y Teclado mecánico.

Restauración local del backup de Render y validación de los datos recuperadosFigura 20. Restauración del backup de Render y validación de los tres productos recuperados.

Backup automático en la nube

La prueba anterior demostraba que la base remota podía respaldarse, pero todavía dependía de una ejecución manual. Para convertirla en un proceso automático creamos un segundo repositorio privado destinado exclusivamente a almacenar las copias cifradas. De esta forma, los respaldos quedan separados del repositorio público de código.

Repositorio privado de GitHub destinado al almacenamiento de backups cifradosFigura 21. Repositorio privado creado para almacenar los respaldos de PostgreSQL.

La URL de PostgreSQL y la frase utilizada para cifrar los archivos se configuraron como Repository Secrets. En el repositorio únicamente se muestran los nombres RENDER_DATABASE_URL y BACKUP_PASSPHRASE; sus valores no aparecen en el workflow ni en las evidencias.

Configuración de los secretos RENDER_DATABASE_URL y BACKUP_PASSPHRASE en GitHub ActionsFigura 22. Secretos de GitHub Actions utilizados por el proceso de backup.

El workflow backup-render.yml automatiza cuatro operaciones: conecta con PostgreSQL en Render, genera el dump mediante pg_dump, comprueba que el respaldo incluya los datos esperados y cifra el archivo antes de guardarlo. La programación diaria se definió mediante cron y se mantuvo workflow_dispatch para poder realizar pruebas manuales.

Workflow de GitHub Actions para automatizar y cifrar los backups de PostgreSQLFigura 23. Workflow de GitHub Actions encargado de generar, validar y cifrar los respaldos.

Programación del workflow:

on:
  schedule:
    - cron: '17 10 * * *'
  workflow_dispatch:
Enter fullscreen mode Exit fullscreen mode

La expresión cron se configuró para una ejecución diaria con objetivo de las 10:17 UTC, equivalente a las 5:17 a. m. en Perú. Para la demostración también se habilitó la ejecución manual del mismo workflow.

Validación de la automatización

La primera validación se realizó mediante Run workflow para comprobar inmediatamente que la conexión, el cifrado y el commit del respaldo funcionaran. La ejecución terminó correctamente y creó el primer archivo con extensión .dump.enc en la carpeta backups del repositorio privado.

Primer archivo de respaldo cifrado generado mediante GitHub ActionsFigura 24. Primer respaldo cifrado creado por GitHub Actions.

Después dejamos activa la programación y revisamos el historial de Actions. Allí apareció una segunda ejecución identificada como Scheduled, diferenciada de la prueba manual. Ambas finalizaron con estado satisfactorio, lo que confirmó que el proceso podía iniciarse sin intervención del usuario.

Ejecución programada Scheduled del backup automático de PostgreSQLFigura 25. Historial con una ejecución manual y una ejecución programada (Scheduled).

La carpeta backups mostró dos archivos cifrados con marcas de tiempo distintas. Esta evidencia final confirmó que la base de Render dispone de un mecanismo periódico de respaldo externo que no requiere mantener encendida la computadora de desarrollo.

Dos archivos de backup cifrados generados y almacenados en el repositorio privadoFigura 26. Respaldos cifrados generados en momentos diferentes dentro del repositorio privado.

Resultados

La implementación permitió comprobar un ciclo completo de protección y recuperación de datos. En local se generaron respaldos mediante pg_dump, se automatizaron con Windows y se restauraron en una base independiente. La recuperación de los tres productos confirmó que los archivos obtenidos eran utilizables y no simples evidencias de ejecución.

La API FastAPI permitió utilizar los mismos datos desde una interfaz web y posteriormente trasladar la solución a Render. El repositorio público quedó separado de las credenciales; Render desplegó la aplicación y PostgreSQL; el cambio a la versión 1.0.1 comprobó el despliegue automático desde GitHub. Finalmente, GitHub Actions automatizó también los respaldos de la base remota, cifrándolos y almacenándolos fuera del entorno de producción.

Componente Validación Resultado
Backup local pg_dump ejecutado desde PowerShell Completado
Automatización local Programador de tareas cada 5 min durante la prueba Verificada
Restauración local pg_restore en base independiente 3 productos recuperados
FastAPI /, /health, /productos y /docs HTTP 200 / conexión correcta
Repositorio público Código sin .env ni backups locales Publicado
Render PostgreSQL + FastAPI Desplegados
Despliegue automático Push a main → versión 1.0.1 Verificado
Backup de Render Dump remoto + restauración local Verificado
GitHub Actions Manual + Scheduled Backups cifrados generados

Conclusiones

  • La validez de una estrategia de backup debe demostrarse mediante restauraciones reales. En este proyecto los respaldos locales y el respaldo de Render fueron recuperados sobre bases independientes y conservaron los tres registros de prueba.

  • Docker y Docker Compose permitieron reproducir PostgreSQL y FastAPI de manera consistente, mientras que las variables de entorno evitaron acoplar la aplicación a una única instalación.

  • La automatización local con PowerShell y el Programador de tareas redujo la intervención manual en el equipo de desarrollo, y GitHub Actions extendió esa automatización a PostgreSQL en la nube sin depender de mantener una computadora encendida.

  • El despliegue automático desde GitHub hacia Render permitió publicar una nueva versión de FastAPI a partir de un push a la rama principal, demostrando un flujo de actualización diferente e independiente del mecanismo de backup.

  • El cifrado y almacenamiento de los respaldos remotos en un repositorio privado separan las copias de recuperación del entorno productivo y del repositorio público de código, fortaleciendo la organización y protección de la solución.

Enlaces del proyecto

Top comments (0)