☀️ 🌙
Artefacto 4 · AI Engineering · Concepto 04 (Fase 5)

De tu Mac a internet

Docker empaqueta el agente en una caja reproducible; Cloud Run la convierte en una URL pública. Con los secretos fuera y el CV blindado.

El agente ya funciona y tiene API. Pero vive en tu Mac: si lo apagas, muere. La Fase 5 lo saca al mundo: lo mete en un contenedor (Docker) y lo publica en Cloud Run, que le da una URL, lo enciende cuando alguien entra y lo apaga cuando nadie lo usa. Todo el despliegue real, con sus salidas, está dentro.

Lo que hay dentro
  1. "En mi máquina funciona" → el contenedor
  2. El Dockerfile: la receta, capa a capa
  3. Dos redes de seguridad (y la trampa que ya te mordió)
  4. Secretos: nunca en la imagen
  5. Cloud Run: la caja se vuelve URL
  6. El despliegue real, paso a paso ✦
  7. Coste, escala a cero y el token
  8. Diccionario del mundo real (para tu CV)

01 "En mi máquina funciona"

La frase más temida de la informática. Tu agente depende de una versión exacta de Python, de librerías, de tu .venv… En otro ordenador, nada de eso está. Un contenedor resuelve esto: empaqueta el sistema operativo mínimo + Python + librerías + tu código en una caja sellada que corre igual en cualquier sitio. Ya lo hiciste con el RAG en el Art.2; esto es memoria muscular.

tu Mac (frágil) imagen Docker (reproducible) Python 3.13 del sistema → python:3.13-slim EXACTO .venv con versiones sueltas → requirements.txt PINEADO "funciona aquí" → funciona idéntico en cualquier nube

02 El Dockerfile: la receta

El Dockerfile es la receta para construir la imagen. Dos decisiones de diseño importan:

FROM python:3.13-slim              # base mínima

COPY requirements.txt .           # ① deps PRIMERO (capa cacheable)
RUN pip install -r requirements.txt

COPY herramientas.py agente.py api.py ./          # ② lista BLANCA
COPY datos_personales/cv_denys.md ./datos_personales/
COPY static/ ./static/

CMD ["sh","-c","uvicorn api:app --host 0.0.0.0 --port ${PORT:-8080}"]

--host 0.0.0.0 es obligatorio dentro de un contenedor: 127.0.0.1 solo se ve a sí mismo. Y $PORT lo inyecta Cloud Run — no lo fijamos a mano.

03 Dos redes de seguridad

Además de la lista blanca del Dockerfile, dos ficheros deciden qué sale de tu Mac:

FicheroControlaAquí sirve para
.dockerignorequé ve el constructor de Dockerque el .env ni entre al contexto de build
.gcloudignorequé sube gcloud a la nubeque suba el CV .md pero NO el .env ni el CV .html

La trampa que ya te mordió en el Art.2:

Si NO existe .gcloudignore, gcloud usa tu .gitignore para decidir qué subir. Y tu .gitignore esconde datos_personales/ (el CV) por privacidad. Resultado: subirías una imagen sin CV → el agente arrancaría roto (no puede leer el CV para el match_cv). En el Art.2 fue el corpus el que faltaba. Por eso el .gcloudignore de esta fase deja pasar cv_denys.md a propósito, y bloquea todo lo sensible. Lo verificamos antes de subir (ver §06).

04 Secretos: nunca en la imagen

La API key de OpenAI y tu token de acceso son secretos. No van en el código, ni en git, ni en la imagen Docker (que es pública dentro de tu proyecto). Van en Secret Manager de GCP, y Cloud Run los inyecta como variables de entorno al arrancar. El código los lee con os.environ — le da igual si vienen de un .env local o de la nube.

.env (local) ─────────┐ ├──► os.environ["OPENAI_API_KEY"] (mismo código) Secret Manager (nube) ─┘ os.environ["APP_TOKEN"]

Creamos un secreto NUEVO para el agente (APP_TOKEN_AGENTE), separado del token del RAG: así puedes revocar uno sin tocar el otro.

05 Cloud Run: la caja se vuelve URL

Cloud Run toma tu imagen y le da una URL pública con HTTPS. Su gracia: escala a cero. Si nadie usa el agente, no hay ninguna copia corriendo y no pagas nada. Cuando llega la primera petición, arranca un contenedor en ~1-2 s (el "arranque en frío") y sirve. Ideal para un demo de portfolio: coste ≈ 0 en reposo.

imagen Docker │ gcloud run deploy --source ▼ Cloud Build (construye en la nube) │ ▼ Cloud Run ──► https://dobe-agente-….run.app (HTTPS, escala a cero) ▲ Secret Manager inyecta OPENAI_API_KEY + APP_TOKEN

06 El despliegue real, paso a paso ✦

Chequeo de privacidad ANTES de subir

Lo primero: preguntar a gcloud qué ficheros subiría, y confirmar que el .env queda fuera y el CV .md dentro. Salida real:

$ gcloud meta list-files-for-upload agente.py api.py herramientas.py requirements.txt Dockerfile datos_personales/cv_denys.md static/index.html .dockerignore .gcloudignore ✅ .env fuera # el secreto no viaja ✅ cv_denys.md dentro # lo necesita el agente ✅ cv_denys.html fuera # la copia personal no viaja ✅ frontend dentro

El deploy

$ gcloud run deploy dobe-agente --source . \ --region europe-southwest1 --allow-unauthenticated \ --set-secrets "OPENAI_API_KEY=OPENAI_API_KEY:latest,APP_TOKEN=APP_TOKEN_AGENTE:latest" Building Container............done Creating Revision............done Routing traffic......done Service [dobe-agente] revision [dobe-agente-00001-rrr] serving 100% of traffic. Service URL: https://dobe-agente-1015586629315.europe-southwest1.run.app

Verificación end-to-end EN PRODUCCIÓN

PruebaResultado
GET /salud200 {estado:ok, protegido:true}
GET / (frontend)200 la página carga
POST /preguntar sin token401 el agente ni se ejecuta
POST /preguntar con token200 turnos:4 · pasos:[analizar,match,redactar] · completado:true

El mismo bucle que probaste en la terminal, ahora corriendo en un contenedor en Europa, detrás de HTTPS y de tu token.

07 Coste, escala a cero y el token

08 Diccionario del mundo real

ConceptoQué es aquíDónde vive fuera
Contenedor / Dockerla caja con el agenteestándar de despliegue en toda la industria
Imagen / capasla receta del Dockerfilecache de capas = builds rápidos en CI/CD
Build contextlo que sube .gcloudignorecontrolar qué ve el constructor: seguridad y peso
Secret ManagerAPI key + token fuera del códigogestión de credenciales en cualquier cloud serio
Cloud Run / serverlessimagen → URL, escala a ceroAWS Lambda, Cloud Functions, Fargate… misma idea
Cold startel arranque de la 1ª peticióncompromiso clásico de lo serverless
HTTPS gestionadoel certificado de la URLCloud Run lo da gratis; en otros sitios es trabajo

Para tu CV, en una frase: «Contenericé el agente con Docker y lo desplegué en Cloud Run con los secretos en Secret Manager y una lista blanca de ficheros verificada antes del build, sirviendo una demo pública protegida por token que escala a cero.» Eso es un flujo de despliegue completo, no un notebook.

→ Y ahora, lucirlo

El agente está vivo: dobe-agente…run.app. Lo último es lucirlo: su página gemela en el portfolio, el enlace desde el roadmap, la tarjeta en denysporynets.github.io, y subir el código publicable (sin el CV, sin el .env) a GitHub.