Desplegar de GitHub a producción: qué puede salir mal

Solo entre el 20% y el 30% de los repositorios se despliegan a la primera sin tocar nada, según los datos que VibeNest publicó el 4 de julio de 2026. El resto falla al desplegar una aplicación GitHub a producción, casi siempre por detalles chicos: la carpeta equivocada de un monorepo, una variable de entorno mal nombrada o un contenedor que arranca y se cae en loop.

En 30 segundos

  • Solo 20-30% deploya limpio: el resto de los repos falla por razones menores, no por Kubernetes ni infraestructura compleja.
  • El monorepo es el enemigo #1: el autodetector agarra la carpeta que no es y buildeas el paquete equivocado.
  • Exit code 137 = OOMKilled: el contenedor se queda sin memoria y entra en crash loop aunque en local anduviera perfecto.
  • Git LFS silencioso: si el build clona solo los punteros, tu modelo o binario de 2 GB nunca llega y el deploy revienta sin decirte por qué.
  • Variables alias vs canónicas: usás DATABASE_URL en local y DB_URL en prod, y la app no conecta a nada.

Ponele que clonás un repo, detectás el stack, buildeás una imagen, corrés un contenedor, le agregás SSL y ruteás el tráfico. En el papel, un problema resuelto. En la práctica, ese “problema resuelto” tiene un montón de grietas donde se cuela todo.

Desplegar una aplicación GitHub a producción es el proceso de tomar el código de un repositorio, empaquetarlo en un contenedor, configurar su entorno de ejecución (variables, puertos, base de datos) y exponerlo en internet con SSL y ruteo. Coolify es una plataforma open source de deployment que automatiza builds, contenedores, routing, certificados y reinicios sin que toques infraestructura a mano.

¿Qué porcentaje de despliegues automatizados funciona sin problemas?

Poco. Según el equipo de VibeNest, que corre su primer camino de deploy sobre Coolify, “aproximadamente un 20-30%” de los repos que ven en la plataforma cruzan la meta con el flujo out-of-the-box. El resto se cae.

Ojo con la trampa conceptual acá: que “el contenedor se creó” no significa que “la app sea usable por los primeros usuarios”. Hay un abismo entre las dos cosas. Un build puede terminar en verde, el proxy puede rutear tráfico, y aun así la app no responde porque le falta la base de datos, o porque bootea una vez y se muere. Ese gap es justamente lo que estos sistemas intentan cerrar. Profundizamos sobre esto en nuestra guía sobre elegir la herramienta de CI/CD adecuada.

¿Cuáles son los problemas más frecuentes entre el repo y la app en vivo?

No son problemas de “Kubernetes es difícil”. Son cosas más pedestres, y por eso duelen más (es más frustrante perder dos horas por una variable mal escrita que por un problema genuinamente complejo). Estos son los que VibeNest enumera:

  • Monorepo con carpeta incorrecta: el deploy agarra la raíz o el paquete que no es y buildea otra cosa.
  • Nixpacks elige mal el build: detecta un build “plausible”, pero no el correcto para tu stack.
  • El proxy apunta al puerto equivocado: rutea a un puerto donde no escucha nada.
  • Sin base de datos en producción: la app espera una DB que en prod todavía no existe.
  • Alias de variable en vez de la canónica: se usa un nombre alternativo de la env var y la conexión falla.
  • Git LFS no clonado: el repo necesita LFS, pero el build solo trajo los archivos puntero.
  • Crash loop o memoria: la app bootea, pasa una vez, y después se cae en loop o se queda sin RAM.

¿Cómo evitar desplegar la carpeta equivocada en un monorepo?

El autodetector solo agarra lo obvio. Si tu repo tiene el frontend, el backend y tres paquetes compartidos conviviendo, la detección automática es una lotería. La solución pasa por dejar de confiar en la magia.

  • Especificá el build path explícito: apuntá a la carpeta exacta (apps/web, services/api) en la config del proyecto.
  • Usá un Dockerfile propio: en vez de dejar que Nixpacks adivine, un Dockerfile define sin ambigüedad qué se buildea y cómo.
  • Configurá tu herramienta de monorepo: si ya usás Turbo, Nx o Lerna, definí el filtro de workspace para que buildee solo el paquete que va a producción.

La regla mental es simple: repos mixtos necesitan config manual. El autodetector es para el caso feliz.

¿Por qué una app se crashea en producción si andaba en local?

La escena clásica: en tu máquina anda impecable, lo mandás a prod y entra en crash loop. ¿Qué cambió? Casi siempre, tres cosas. Te puede servir nuestra cobertura sobre cómo elegir entre GitHub Actions y Jenkins.

El sospechoso número uno es la memoria. Si ves exit code 137, es OOMKilled: el contenedor pidió más RAM de la que tenía asignada y el kernel lo mató. En tu notebook con 16 GB no se notaba; en un contenedor con 256 MB de límite, se muere al primer pico. Subís el límite de memoria o bajás el consumo de la app.

Los otros dos: dependencias que están en tu entorno local pero no en el contenedor (una librería de sistema, un binario que asumías instalado), y variables de entorno críticas que no configuraste en prod. Para debuggear cualquiera de las tres, andá directo a los logs del contenedor. Ahí está el motivo real, no en tu cabeza.

¿Qué es Git LFS y cuándo es imprescindible en el deploy?

Git LFS (Large File Storage) es una extensión de Git que guarda archivos grandes (binarios, videos, datasets, modelos de IA) fuera del historial normal y en el repo deja solo un puntero de texto que apunta al archivo real.

Acá viene el problema: si el proceso de build clona el repo sin LFS habilitado, se trae los punteros, no los archivos. Y falla en silencio. El build “clona”, el archivo de 2 GB nunca baja, y tu app arranca sin el modelo o sin el asset que necesita. Es imprescindible cuando versionás modelos de machine learning, assets binarios pesados o una base de datos semilla dentro del repo. Cubrimos ese tema en detalle en nuestra guía sobre configurar hreflang en aplicaciones multidioma.

¿En qué se diferencian las variables de entorno de local y las de producción?

El error más tonto y más común: nombrar distinto la misma variable. En local tenés DATABASE_URL, en prod la config dice DB_URL, y la app busca una que no existe. No conecta a nada y no siempre te avisa con claridad.

  • Usá siempre el nombre canónico: uno solo, el mismo en todos los entornos. Nada de alias “por comodidad”.
  • Nunca commitees el .env: en local usás dotenv, en producción un secrets manager. El archivo con secretos jamás va al repo.
  • Verificá antes de deployar: chequeá que cada variable que la app espera esté seteada en el entorno de destino con el nombre exacto.

Comparativa: dónde falla cada capa del deploy

ProblemaSíntoma típicoSolución concreta
Carpeta de monorepoBuildea el paquete que no esBuild path explícito o Dockerfile propio
Stack mal detectadoNixpacks elige build plausible pero erróneoDockerfile que fije runtime y comando
Puerto del proxy502/504, no responde nadaAlinear puerto expuesto con el que escucha la app
Falta la base de datosLa app bootea y no conectaProvisionar la DB antes del primer deploy
Variable alias vs canónicaConexión nula, config vacíaNombre canónico único en todos los entornos
Git LFSFalla silenciosa, falta el archivo pesadoHabilitar LFS en el clone del build
Memoria / crash loopExit code 137 (OOMKilled)Subir límite de RAM o reducir consumo
desplegar aplicación github a producción diagrama explicativo

¿Cómo cerrar el gap entre “contenedor creado” y “app usable”?

Esa es la capa que VibeNest dice estar automatizando sobre Coolify: detectar el stack correcto, configurar las variables, probar la conectividad con la base de datos, validar puertos. El primer pase es a propósito aburrido y normal. Si el repo es directo, Coolify lo deploya y listo. El laburo útil arranca cuando el repo está “casi deployable, pero no”.

Si vas a correr algo de esto en tu propia infraestructura, la capa de más abajo (el servidor, el VPS, la red) tenés que resolverla igual. Para hosting y servidores en Argentina podés apoyarte en donweb.com y montar Coolify encima, que se ocupa de la parte tediosa: builds, contenedores, routing, SSL, logs y reinicios.

Errores comunes al desplegar desde GitHub

  • Confiar ciegamente en la autodetección: anda para el 20-30% fácil. Para el resto, config manual o Dockerfile, sin excusas.
  • Ignorar los logs del contenedor: la gente adivina la causa del crash en vez de leer el log, que la mayoría de las veces dice exactamente qué pasó (exit code 137, módulo faltante, variable nula).
  • Deployar sin provisionar la base de datos: la app compila y bootea igual, así que parece que “anduvo”. Después no conecta a nada y recién ahí te das cuenta.
  • Versionar archivos pesados sin LFS o sin habilitarlo en el build: el deploy se trae los punteros y tu binario de 2 GB queda en el molde.

Preguntas Frecuentes

¿Qué errores pueden ocurrir al desplegar una aplicación desde GitHub?

Los más frecuentes son desplegar la carpeta equivocada en un monorepo, que el detector de stack elija un build erróneo, el proxy apuntando a un puerto donde no escucha la app, variables de entorno mal nombradas, Git LFS sin habilitar y contenedores que se caen por falta de memoria. Según VibeNest, el 70-80% de los repos falla por alguna de estas razones menores.

¿Por qué mi aplicación se crashea después del deploy a producción?

La causa más común es memoria: un exit code 137 indica OOMKilled, o sea que el contenedor superó su límite de RAM y el sistema lo mató. Otras causas son dependencias que existen en local pero no en el contenedor y variables de entorno críticas sin configurar. Los logs del contenedor te muestran el motivo exacto. Más contexto en nuestra guía sobre seleccionar el modelo de IA correcto.

¿Cómo configuro bien las variables de entorno en el deployment?

Usá el mismo nombre canónico de cada variable en todos los entornos, sin alias como DB_URL en un lado y DATABASE_URL en otro. En local manejalas con dotenv y en producción con un secrets manager. Nunca commitees el archivo .env al repositorio y verificá que cada variable esperada esté seteada antes de deployar.

¿Qué hago si se desplegó la carpeta incorrecta en un monorepo?

Especificá el build path de forma explícita apuntando a la carpeta exacta del servicio, o agregá un Dockerfile propio que defina sin ambigüedad qué se buildea. Si usás Turbo, Nx o Lerna, configurá el filtro de workspace para que solo se construya el paquete destinado a producción.

¿Cómo prevengo los crash loops después del despliegue?

Empezá por revisar los logs del contenedor para identificar la causa. Si aparece exit code 137, subí el límite de memoria asignado o reducí el consumo de la app. Verificá también que todas las dependencias del sistema estén en la imagen y que las variables de entorno críticas estén configuradas antes del arranque.

Conclusión

El deploy desde GitHub no falla por lo difícil, falla por lo chico. Los datos de VibeNest lo dejan claro: solo 20-30% de los repos cruzan limpio, y el resto tropieza con una carpeta mal elegida, una variable con nombre distinto o un contenedor sin RAM suficiente. ¿La buena noticia? Todas esas fallas son conocidas y se anticipan.

Antes de tu próximo deploy, hacé el checklist: build path explícito si es monorepo, nombres de variables canónicos, LFS habilitado si tenés archivos pesados, base de datos provisionada y límites de memoria realistas. Y cuando algo se caiga igual, abrí los logs del contenedor antes de adivinar. La respuesta casi siempre está ahí escrita.

Fuentes

Te puede interesar...