Este repositorio utiliza Docker para simplificar el desarrollo de los servicios backend y frontend. Las siguientes secciones explican cómo funciona la configuración de Docker, cómo construir y ejecutar los contenedores, y cómo están integrados los repositorios.
El repositorio ai-portfolio incluye los proyectos backend y frontend como submódulos de Git. Se añaden con los siguientes comandos:
# Añadir submódulo del backend
git submodule add git@github.com:ai-portfolio-2026/backend.git backend
# Añadir submódulo del frontend
git submodule add git@github.com:ai-portfolio-2026/frontend.git frontendDespués de agregar los submódulos, es necesario inicializarlos y actualizarlos:
git submodule init
git submodule updateEstos comandos crean y rellenan el archivo .gitmodules, que registra la URL y la ruta de cada submódulo, permitiendo que Git los gestione correctamente.
El archivo docker-compose.yml define los siguientes servicios:
- redis – Base de datos en memoria utilizada para caché de embeddings y respuestas, lo que acelera significativamente las consultas repetidas.
- backend – construido a partir de
backend/Dockerfile - frontend – construido a partir de
frontend/Dockerfile
Nota Importante: Esta configuración de
docker-composeestá diseñada específicamente para desarrollo local. No debe utilizarse tal cual en producción.
Para ejecutar todo el stack:
docker compose up --buildEste comando construye las imágenes (si no están ya construidas) y arranca ambos contenedores, exponiendo los puertos definidos en el archivo de composición.
Aunque docker-compose es una herramienta válida para entornos de producción, el archivo docker-compose.yml incluido en este repositorio está configurado exclusivamente para desarrollo local.
A continuación se detallan las razones técnicas y las diferencias arquitectónicas entre ambos entornos:
La configuración actual prioriza la velocidad de iteración sobre la estabilidad, lo que la hace inadecuada para producción por dos motivos principales:
- Build en Tiempo de Ejecución (
build:): Construye la imagen desde el código fuente al iniciar el contenedor. En producción, esto es ineficiente y propenso a errores. El estándar es construir la imagen una única vez (CI/CD) y desplegar ese artefacto inmutable. - Volúmenes de Código (
volumes:): Monta el código local en el contenedor para permitir hot-reload. En producción, el código debe estar sellado dentro de la imagen para garantizar la inmutabilidad y evitar modificaciones accidentales en tiempo de ejecución.
En un servidor tradicional (VPS), la configuración de producción (docker-compose.prod.yml) difiere significativamente, ya que consume imágenes pre-construidas y optimizadas:
Configuración Local (Desarrollo):
backend:
build: ./backend # Construye desde fuente
volumes:
- ./backend:/app # Código mutable (hot-reload)
command: python manage.py runserver # Servidor de desarrolloConfiguración Ideal (Producción):
backend:
image: namespace/backend:v1.0 # Imagen inmutable y versionada
restart: always # Política de reinicio
# Sin volúmenes de código fuente
command: gunicorn app:main # Servidor de aplicaciones WSGIPara el despliegue actual en Render (PaaS), la plataforma actúa como orquestador de contenedores, reemplazando la función de docker-compose.
En este modelo:
- Imágenes: Se construyen y almacenan externamente (Docker Hub) a través de GitHub Actions.
- Orquestación: Render descarga estas imágenes y gestiona el ciclo de vida, redes y volúmenes de los servicios.
A continuación se detalla el proceso configurado para automatizar la construcción y despliegue de la imagen Docker.
Para que GitHub Actions pueda subir la imagen a Docker Hub, primero se deben configurar las credenciales (usuario y token) en Settings > Secrets and variables > Actions del repositorio.
El archivo .github/workflows/main.yml define los pasos para construir la imagen y subirla a Docker Hub automáticamente cada vez que se hacen cambios.
Una vez que el workflow se ejecuta exitosamente, la imagen estará disponible en Docker Hub. La URL de la imagen (namespace/repo:tag) es la que necesitaremos para Render.
Finalmente, en el panel de control de Render.com, se configura el servicio para que utilice la imagen específica de Docker Hub. Render tirará de esta imagen para desplegar la aplicación.
El Dockerfile del backend utiliza uv para la gestión de dependencias y ejecuta un script de entrypoint:
- Imagen Base – Python 3.12 slim.
- Instalar uv –
uvse instala para resolver e instalar paquetes de Python de forma eficiente. - Copiar Código – El código fuente del backend se copia dentro de la imagen.
- Entry Point –
docker-entrypoint.shse establece como entrypoint del contenedor. Este script activa el entorno virtual, ejecuta migraciones y arranca el servidor.
La imagen resultante se llama ai-portfolio-backend (etiquetada por Docker Compose).
El Dockerfile del frontend es sencillo:
- Imagen Base – Node.js LTS.
- Copiar Código – Se copia el código fuente del frontend.
- Instalar Dependencias –
npm install. - Construir –
npm run buildgenera los activos de producción. - Servir – Un servidor ligero (por ejemplo,
serveonginx) sirve los archivos construidos.
La imagen se llama ai-portfolio-frontend.
- Docker Engine (>= 24.x)
- Docker Compose (v2)
- Git con claves SSH configuradas para la organización en GitHub
- Clonar el repositorio (incluyendo submódulos):
Si ya se clonó sin
git clone --recurse-submodules git@github.com:ai-portfolio-2026/ai-portfolio.git cd ai-portfolio--recurse-submodules, ejecutar:git submodule init git submodule update
- Construir y ejecutar:
docker compose up --build
- Acceder a los servicios:
- API del backend:
http://localhost:<backend_port> - UI del frontend:
http://localhost:<frontend_port>
- API del backend:
Para detener y eliminar contenedores, redes e imágenes:
docker compose down --rmi all


