|

Deploy full stack: 4 errores típicos y su arreglo

En pocas palabras: Un deploy full stack publica frontend y backend con su base de datos y los conecta con la configuración correcta. En un caso de dev.to del 10 de octubre de 2026, Django en Render y React en Vercel fallaron por CORS, migraciones, rewrites y secretos, no por código.

Un deploy full stack falla casi siempre por configuración, no por código. En un caso publicado el 10 de octubre de 2026 en dev.to, un pasante subió un backend Django a Render y un frontend React a Vercel, y tuvo que corregir CORS, migraciones, rewrites y secretos.

Un deploy full stack es el proceso de publicar las dos mitades de una aplicación, el frontend que corre en el navegador y el backend con su base de datos, y conectarlas con la configuración correcta. Sirve para que usuarios reales usen la app fuera de tu máquina, y le toca a quien desarrolla o mantiene el proyecto. Lo que anda en localhost no garantiza nada.

En 30 segundos

  • CORS: el navegador bloquea llamadas entre orígenes distintos salvo que el backend las autorice. El autor habilitó el dominio exacto de Vercel.
  • Migraciones: la base PostgreSQL nueva no tenía tablas. Agregó migrate al build command de Render.
  • 404 al recargar: una regla de rewrite en vercel.json manda todas las rutas a index.html.
  • Secretos: SECRET_KEY, URL de la base y URL de la API pasaron a variables de entorno.
  • Alcance: es el relato de un pasante con un proyecto, no una guía oficial. Lo contrastamos con MDN, Vercel y Render.

¿Cómo hacer un deploy full stack con frontend y backend separados?

En el caso, el backend Django REST Framework con PostgreSQL gestionado corre en Render y el frontend React con Vite corre en Vercel, con login por JWT y tareas separadas por usuario. Cada pieza tiene su propio dominio, así que el navegador trata las llamadas como cruces entre orígenes. Hay otra opción, servir todo desde un mismo servidor, pero la fuente no la prueba y no podemos compararlas con datos.

¿Por qué el CORS bloquea las llamadas a la API después del deploy?

deploy full stack diagrama explicativo

El navegador bloquea la llamada porque el frontend y la API tienen orígenes distintos y el backend no autorizó al frontend a leer la respuesta. Según MDN, el servidor lo declara con el header Access-Control-Allow-Origin. El pasante puso el dominio exacto de Vercel en lugar de permitir todos los orígenes.

Subís el frontend, abrís la URL, la página carga perfecta, hacés clic en registrarte, la consola se llena de rojo, mirás la pestaña Network y recién ahí entendés que el navegador ni siquiera dejó leer la respuesta porque el backend nunca nombró a tu dominio.

Ojo con el comodín. MDN aclara que, con requests con credenciales, el servidor tiene que indicar un origen concreto y no puede usar *. Para una API pública de solo lectura el asterisco puede servir, pero en una app con login conviene la lista explícita. Cubrimos el despliegue del frontend en nuestra guía para publicar una app React con Vite.

Otro detalle de MDN: los fallos de CORS no le dan detalles al código JavaScript, que solo sabe que hubo un error. El motivo está en la consola del navegador.

Una inferencia nuestra, no del autor: si mandás el JWT en el header Authorization, ese header no está en la lista de headers seguros que detalla MDN, así que el navegador va a hacer un preflight con OPTIONS. El backend tiene que responder bien a esa consulta, no solo al GET o POST final.

¿Cómo correr las migraciones de Django en Render si no hay shell?

Poné el comando migrate dentro del build command, así corre en cada deploy. Eso hizo el autor porque, según su relato, el plan gratuito de Render no tiene shell ni release command. El síntoma era un error de servidor al registrarse: la base PostgreSQL nueva no tenía tablas.

Dicho esto, contrastalo. La guía de Render para Django usa un script build.sh como Build Command, con DATABASE_URL (la URL interna de la base) y SECRET_KEY (generada desde el panel) como variables de entorno. La misma guía crea el admin de Django desde el Render Shell, así que antes de asumir el límite del plan gratuito, revisá la documentación vigente y tu plan.

¿Por qué una app React da 404 al refrescar la página en Vercel?

React Router resuelve las rutas en el navegador, así que el servidor no tiene ningún archivo en /tasks y responde 404. La solución del caso es una regla en vercel.json que envía todas las rutas a index.html. La URL que ve el usuario no cambia. Hablamos de esto en nuestra guía para armar un e-commerce full-stack profesional.

Este es el patrón habitual (la sintaxis la armamos nosotros, no la copia la fuente, así que comprobala contra la referencia de Vercel):

{
 "rewrites": [
 { "source": "/(.*)", "destination": "/index.html" }
 ]
}

La documentación de Vercel, actualizada el 25 de agosto de 2026, lista rewrites entre las propiedades de vercel.json y aclara que solo podés usar un archivo de configuración por proyecto (vercel.json, vercel.toml o vercel.ts).

¿Cómo manejar secretos y variables de entorno en producción?

Cargalos en el panel de cada plataforma y leelos desde el código, sin commitearlos a Git. El autor movió la secret key, la URL de la base y la URL base de la API a variables de entorno, y así el mismo código corre en local y en producción.

  • Backend (Render): SECRET_KEY, DATABASE_URL y los orígenes permitidos para CORS. La guía de Render agrega WEB_CONCURRENCY en 4.
  • Frontend (Vercel): la URL de la API. Es la única que el caso menciona para esta parte.
  • DEBUG: según Render, nunca en True en producción. Podés detectar que corrés en Render con la variable RENDER y tomar el host de RENDER_EXTERNAL_HOSTNAME para ALLOWED_HOSTS.

Con Vite, las variables con prefijo VITE_ terminan dentro del bundle que baja el navegador. Ahí va la URL de la API, nunca un secreto.

Checklist para probar tu app full stack en producción

La lista del autor tiene cinco puntos y alcanza para una primera app:

  • Variables de entorno cargadas en el dashboard.
  • Migraciones aplicadas.
  • CORS con el dominio real del frontend.
  • Rewrite para el ruteo del lado del cliente.
  • Cuenta nueva que se registra, se loguea y completa todo el CRUD en el sitio real.

La lección más valiosa del relato es la última. El autor descubrió que su app no tenía página de registro recién cuando intentó crear una cuenta en la versión desplegada, algo que el testing local nunca lo obligó a hacer. Su consejo: desplegá temprano y en pasos chicos, y leé los logs antes de tocar el código. Tema relacionado: desplegar tu web gratis en Vercel.

Propuesta editorial, que no sale de la fuente y que no probamos: abrí el sitio en una ventana de incógnito con la consola abierta, entrá por URL directa a una ruta interna como /tasks, registrá un usuario nuevo y revisá en Network que la respuesta al OPTIONS traiga tu dominio en Access-Control-Allow-Origin. Si todo eso pasa, el deploy está bastante sano.

Si preferís un servidor propio en Argentina en vez de plataformas gestionadas, donweb.com es una alternativa a evaluar. Ahí vas a tener que armar vos lo que Render y Vercel resuelven por defecto.

Errores comunes al hacer el deploy

  • Dejar el asterisco en CORS “para que ande”. Con credenciales ni siquiera funciona, según MDN. Poné la lista de dominios reales.
  • Cargar mal el origen. Un origen es dominio, esquema y puerto. Si ponés http en vez de https, o una barra final, es probable que no coincida.
  • Probar solo con el usuario que creaste en local. La base de producción empieza vacía y el flujo de alta recién se prueba ahí.
  • Dejar DEBUG en True porque “total, es una app chica”. Render lo desaconseja en producción.
  • Meter un secreto en una variable VITE_. Queda visible para cualquiera que abra el bundle.

Un límite del caso: es un solo proyecto, sin métricas ni comparación con otras arquitecturas. Sirve de lista de síntomas, no de prueba de que esta combinación sea la mejor.

Preguntas Frecuentes

¿Por qué mi app React da 404 al recargar la página en Vercel?

Porque el servidor busca un archivo en esa ruta y las rutas de React Router solo existen en el navegador. Se arregla con un rewrite en vercel.json que envía todo a index.html.

¿Cómo soluciono el error de CORS entre mi frontend y mi backend en producción?

Hacé que el backend responda con Access-Control-Allow-Origin igual al dominio exacto del frontend. Si usás credenciales no podés usar el comodín *, y el detalle del error está en la consola del navegador. Más contexto en errores de deploy que no aparecen en local.

¿Cómo ejecuto las migraciones de Django en Render sin acceso a shell?

Agregá el comando migrate al build command, como hizo el autor del caso. Render documenta un build.sh como build command; confirmá en su documentación qué permite tu plan.

¿Cómo configuro variables de entorno para producción sin subirlas a Git?

Cargalas en el dashboard de la plataforma y leelas desde el código. En Render, SECRET_KEY y DATABASE_URL se definen en el servicio web, y el frontend recibe la URL de la API por su propia variable.

¿Qué tengo que revisar después de hacer el deploy de mi primera app full stack?

Revisá variables cargadas, migraciones aplicadas, CORS con el dominio real y el rewrite del frontend. Después registrá una cuenta nueva y completá todo el CRUD en el sitio en vivo.

Conclusión

El relato del 10 de octubre de 2026 no inventa nada nuevo, pero ordena cuatro fallas que cualquiera se topa en su primer deploy full stack, y las docs de MDN, Vercel y Render confirman la lógica detrás de cada arreglo. Lo que no demuestra es que esta arquitectura sea la mejor ni que el plan gratuito de Render siga igual hoy. Antes de tu próximo deploy, armá el checklist de cinco puntos, revisá los logs primero y probá el sitio como un desconocido.

Fuentes

Te puede interesar...