From n00b to ZeroCool / Origen
Deploy o no existe: la primera vez que pones algo real en internet
Haz tu primer deploy sin humo: dominio, HTTPS, env vars, CI/CD, logs y rollback. Pasos reales y errores típicos que sí pegan.
Lo que vale la pena leer aquí
Le mandas el link a alguien y: boom. CORS. Variables de entorno en undefined. Build que no se generó. O el clásico 502 que se siente como “mejor dedícate a otra cosa”.
Cuando tu app “jala en mi compu” y en internet se muere
Son las 11:47 pm. Mañana hay demo. Tu laptop ya pidió jubilación, pero tu proyecto corre precioso en localhost. Te sientes listo.
Le mandas el link a alguien y: boom. CORS. Variables de entorno en undefined. Build que no se generó. O el clásico 502 que se siente como “mejor dedícate a otra cosa”.
Ahí aprendes la regla con la que muchos nos golpeamos la cara: deploy o no existe. Si nadie más lo puede abrir (sin que tú estés explicando “es que en mi máquina…”), tu app sigue en trámite.
Va una guía sin humo para subir algo real: con dominio, HTTPS, env vars, logs y un plan B para cuando (no si) se rompa.
Qué vas a sacar de aquí
- Elegir una ruta de deploy sin convertirte en DevOps de golpe (pero sin ingenuidad).
- Subir un frontend + backend sencillo con buenas prácticas mínimas.
- Configurar dominio/DNS y HTTPS sin rezarle al módem.
- Manejar variables de entorno, secretos y builds.
- Ver logs, detectar errores y hacer rollback sin entrar en pánico.
- Checklist final para que tu deploy no dependa de la suerte.
Contexto práctico: tres niveles de “subir algo”
Antes de tocar teclas, decide qué estás subiendo. Esto te ahorra horas de talacha por escoger la herramienta equivocada.
1) Frontend estático (HTML/CSS/JS, React/Vite, Next estático)
- Ideal si tu app es UI + llamadas a APIs.
- Deploy casi en corto: Vercel / Netlify / Cloudflare Pages.
- Para proyectos personales, casi siempre sale gratis.
2) Fullstack con backend (API, auth, DB)
- Ya necesitas runtime (Node/Python/etc.), variables y probablemente base de datos.
- Rutas comunes:
- Frontend en Vercel/Netlify + API en Render/Fly.io/Railway.
- Todo junto en Render/Fly.io (más simple al inicio; menos “microservicios por moda”).
3) “Lo monté en mi compu” (puerto abierto + IP pública)
- Sí se puede. También se puede cruzar Periférico en chanclas.
- Para aprender está bien; para algo real, mejor usa un proveedor.
Dos realidades que pegan mucho por acá:
- En LATAM, el internet de casa puede estar detrás de CGNAT. Traducción: aunque abras puertos, desde fuera no te ven. No es tu culpa.
- En la chamba o la escuela a veces “deploy” es mandar un zip por WhatsApp. En cuanto haces un deploy de verdad, ya no hay vuelta.
Guía principal: tu primer deploy real (sin volverte mártir)
Ruta muy común y efectiva para empezar:
- Repo en GitHub
- Frontend en Vercel
- Backend en Render (Fly.io también jala, pero Render suele ser más amable para primer setup)
- Dominio opcional (pero recomendado)
Si tu proyecto es solo frontend, brinca la parte de backend.
Paso 0: deja tu repo listo para producción (modo adulto funcional)
Checklist rápida antes de subir nada:
- Tu app corre con comandos claros:
- Frontend:
npm run dev(local) ynpm run build(producción) - Backend:
npm startonpm run start
- Frontend:
- Tu
READMEmínimo dice:- cómo instalar (
npm i) - cómo correr
- qué variables de entorno necesita
- cómo instalar (
- No subas secretos al repo (ni “nomás tantito”).
Tip de guerra: si ya subiste un .env a GitHub una vez, aunque lo borres, puede quedar en el historial. Rota llaves. Sí, duele. Pero duele más un leak en production.
Paso 1: separa configuración (env vars) de tu código
En local sueles tener algo así:
# .env (NO se sube)
DATABASE_URL=...
JWT_SECRET=...
API_URL=http://localhost:3001
En producción:
- Nunca uses
localhost. API_URLapunta al dominio real de tu backend.
Ejemplo Node/Express:
const port = process.env.PORT || 3001;
app.listen(port, () => console.log(`Listening on ${port}`));
Esto evita el error típico estilo Heroku/Render: tu app ignora el puerto del proveedor, “corre”, pero nadie puede entrar.
Paso 2: deploy del backend (Render) con un Express básico
2.1 Requisitos mínimos
- Un repo con tu backend.
package.jsoncon scripts:
{
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js"
}
}
2.2 Crear el servicio
- En Render: New + → Web Service.
- Conecta tu repo.
- Define:
- Build command:
npm install - Start command:
npm start
- Build command:
- Agrega env vars en el panel (no en tu código).
- Deploy.
2.3 Prueba que vive
Crea un endpoint de salud:
app.get('/health', (req, res) => res.json({ ok: true }));
Abre https://tu-backend.onrender.com/health.
Si eso no responde, no te saltes al frontend. Primero deja el backend estable.
Paso 3: deploy del frontend (Vercel) sin drama
- En Vercel: Add New → Project.
- Importa repo.
- Que detecte el framework (Vite/Next/etc.).
- Configura env vars:
VITE_API_URLoNEXT_PUBLIC_API_URLsegún tu stack.
Ejemplo Vite:
VITE_API_URL=https://tu-backend.onrender.com
En tu código:
const apiUrl = import.meta.env.VITE_API_URL;
fetch(`${apiUrl}/health`);
Deploy.
Momento real: si jala en local pero en prod no, muchas veces es porque la env var en Vercel está mal escrita o la pusiste en Preview y no en Production. Pasa más de lo que nos gusta admitir.

Paso 4: conecta frontend y backend (CORS, rutas y headers)
El error más humillante del primer deploy: CORS.
En Express:
npm i cors
import cors from 'cors';
const allowed = [
'http://localhost:5173',
'https://tu-frontend.vercel.app'
];
app.use(cors({
origin: function (origin, cb) {
if (!origin) return cb(null, true); // Postman/health checks
if (allowed.includes(origin)) return cb(null, true);
return cb(new Error('Not allowed by CORS'));
}
}));
Tradeoff real:
- Permitir
*te desbloquea… pero si hay auth/cookies, te abres puertas que no querías abrir. - Mejor whitelist de orígenes y actualízala cuando cambies dominio.
Paso 5: dominio + DNS (la parte que se siente como brujería)
No es obligatorio, pero cambia el juego: deja de verse “demo” y se empieza a sentir “producto”. Y si le estás chambeando para un cliente, un dominio es el mínimo para que no te regateen.
5.1 Conceptos que sí necesitas
- A record: apunta un dominio a una IP.
- CNAME: apunta un subdominio a otro dominio (común con Vercel).
- TTL: cuánto tarda en propagarse. Si lo pones alto, cualquier cambio te persigue horas.
5.2 Setup típico
www.tudominio.com→ CNAME a Vercelapi.tudominio.com→ CNAME a Render (si te lo permite) o al hostname del backend
Realidad mexicana: si compraste dominio en un proveedor barato, su panel DNS puede ser un laberinto. Respira, toma screenshots, y revisa dos veces que no metiste espacios raros o puntos extra.
Paso 6: HTTPS sin llorar
La buena noticia: Vercel y Render te ponen HTTPS casi automático.
Lo que sí pasa:
- El certificado no se emite hasta que DNS esté bien.
- Puede tardar. Si traes deadline encima, no lo dejes para el último día.
Paso 7: logs, monitoreo mínimo y cómo no quedarte ciego
Cuando algo falla en production, ya no tienes tu consola feliz de local. Necesitas:
- Logs del proveedor (Render: Logs).
- Logs del frontend (Vercel: Build logs / Functions logs si aplica).
En backend, loguea errores con algo útil:
app.use((err, req, res, next) => {
console.error('[ERROR]', err.message);
res.status(500).json({ error: 'Internal error' });
});
No metas datos sensibles al log (tokens, passwords). Luego alguien pide “mándame un screenshot del log” y se te arma el problema gratis.
Paso 8: rollback (porque la vida pega)
Subes un cambio, se rompe todo y tu jefe te escribe “¿qué moviste?” mientras tú sigues en pijama.
- Vercel: puedes promover un deploy anterior.
- Render: revisa el historial de deploys y redeploy del commit previo.
Plan simple:
- Identifica el último commit “bueno”.
- Re-deploy ese commit.
- Con el servicio arriba, debuggeas con calma.
Tradeoff real: CI/CD rápido te da velocidad, pero también te deja romper producción más rápido. La solución no es “no deployes”, es tener rollback y pruebas mínimas.
Screenshots sugeridos
- Panel de Vercel mostrando:
- Deploy exitoso
- Variables de entorno configuradas
- Dominio conectado
- Panel de Render mostrando:
- Build logs
- Env vars
- URL pública del servicio
- Configuración DNS (A/CNAME) en tu registrador
- Error CORS en consola del navegador y la corrección
- Endpoint
/healthrespondiendo en el navegador
Errores comunes y cómo salir vivo
1) “Funciona local, en producción 404/500”
Causa: rutas distintas, build que no corre, o start command incorrecto.
- Revisa build logs.
- Asegúrate que existe
npm run buildsi tu framework lo necesita. - Verifica
Start Command.
2) Variables de entorno undefined
Causa: nombre mal escrito o no reiniciaste el deploy.
- Revisa mayúsculas y prefijos (
VITE_,NEXT_PUBLIC_). - En muchos proveedores, cambiar env vars requiere redeploy.
3) CORS bloqueando todo
Causa: origin no permitido.
- Agrega tu dominio real a la whitelist.
- No uses
*si hay cookies/sesión.
4) Base de datos “se cae” o no conecta
Causa: IP allowlist, URL mal, SSL requerido.
- Copia
DATABASE_URLdirecto del proveedor. - Revisa si necesita
?sslmode=require(común en Postgres administrado).
5) Tu backend se duerme (free tier) y la primera petición tarda años
Causa: planes gratis con cold start.
- Solución real: plan de pago.
- Solución de supervivencia: endpoint ping (no ideal, pero pasa mucho en proyectos personales).

Checklist final (deploy o no existe)
- Tengo un repo con build y start claros.
- Mis secretos NO están en Git.
- Backend responde
/healthen internet. - Frontend consume
API_URLdesde env vars (no hardcodeado). - CORS permite mi dominio real.
- Tengo HTTPS activo.
- Dominio y DNS apuntan bien (y entendí qué es CNAME/A).
- Sé dónde ver logs.
- Sé hacer rollback al último deploy estable.
- Tengo un “README para mi yo del futuro”.
FAQ
1) ¿Cuál es el deploy más fácil para empezar?
Si es solo frontend: Vercel o Netlify. Si hay backend: frontend en Vercel + backend en Render suele ser la ruta menos dolorosa.
2) ¿Necesito comprar dominio desde el día 1?
No, pero ayuda. Para portfolio y demos rápidas, el subdominio del proveedor está bien. Si ya lo van a usar clientes/usuarios, dominio propio se siente más serio.
3) ¿Qué pasa si mi app usa .env y lo subo por error?
Asume compromiso: rota keys (API keys, DB passwords), invalida tokens si aplica y limpia historial si es necesario. Borrarlo del repo no basta.
4) ¿Cómo sé si mi problema es DNS o mi servidor?
Si el dominio no resuelve o apunta a otro lado, es DNS. Si resuelve pero da 500/502, es tu app o el servicio. Prueba primero con la URL directa del proveedor (sin dominio).
5) ¿CI/CD es obligatorio desde el inicio?
No, pero tener deploy automático por push te ahorra un buen de workflow manual. El mínimo: que el deploy sea reproducible y que puedas regresar a una versión estable.
Siguiente episodio
Ya que tu app vive en internet, toca lo que separa “demo” de “producto”: logs de verdad, métricas y alertas.
Porque el bug que no ves igual te cobra la factura… nomás que a las 3 am.
Idea para cerrar bien este post: toma una sola práctica de aquí y conviértela en algo que tu equipo pueda aplicar hoy.
Cuando un artículo aterriza en decisiones reales, deja de ser contenido y se vuelve ventaja.


