🚀 2.11 · Deploy: lleva tu API de localhost a internet

⏱ 4h 00min ⚡ 80 XP 🏅 Profesional Junior 📖 Backend FullStack
"El código en tu laptop no existe hasta que está en producción."

🎯 Objetivo del tema

Al terminar este tema serás capaz de: Al terminar este tema serás capaz de desplegar tu API de Node.js en plataformas modernas como Railway, Render o Vercel. Configurarás variables de entorno, dominio personalizado, HTTPS automático, y monitoreo básico. Tu API dejará de ser 'solo en mi PC' y será accesible desde cualquier parte del mundo.
🎬
Video del instructor

El administrador aún no ha insertado un video para esta sección.

🗺️ Mapa del tema

Construir la API es solo la mitad del trabajo: la otra mitad es llevarla a internet. En la era del cloud, el deploy es sorprendentemente fácil: subes tu código a GitHub, conectas una plataforma de deploy (Railway, Render, Vercel), y en 2 minutos tienes tu API en producción con HTTPS automático. Vamos a ver el flujo completo, las mejores plataformas de 2024-2025, y los errores más comunes del primer deploy.

1. Las 3 mejores plataformas de deploy para Node.js

Railway, Render, Vercel: comparativa honesta.

2. El flujo completo: de GitHub a producción

Push, conectar repo, configurar env vars, deploy.

3. Variables de entorno en producción

Cómo configurar JWT_SECRET, MONGODB_URI, etc. sin subirlos a Git.

4. Dominio personalizado y HTTPS

De mi-app.railway.app a mi-app.com con HTTPS automático.

5. Monitoreo y logs en producción

Cómo saber si tu API está caída y qué está fallando.

6. Errores comunes del primer deploy

Los 7 problemas típicos y cómo solucionarlos.

2.11.1 Las 3 mejores plataformas de deploy para Node.js

En 2024-2025 hay 3 plataformas que dominan el deploy moderno de Node.js: Railway, Render y Vercel. Las 3 tienen plan gratuito, HTTPS automático, y deploy con cada push a GitHub. La elección depende de tu caso de uso, no del precio (las 3 son baratas o gratis para empezar).

📷 Imagen referencial: Flujo de deploy moderno: laptop con código -> commit a GitHub -> CI/CD automático -> deploy en cloud (Railway/Render) -> URL pública con HTTPS -> usuarios.
AspectoRailwayRenderVercel
Plan gratuito500h/mes + $5 de crédito.750h/mes (servicios web).Hobby plan (suficiente para aprender).
Mejor paraBackend completo (Node + BD).Backend y frontend.Frontend + serverless functions.
Soporta DockerSí.Sí.Limitado (mejor serverless).
Tiempo de deploy2-3 min desde push.2-3 min desde push.30 seg (es su especialidad).
Custom domainSí (gratis).Sí (gratis).Sí (gratis).
HTTPS automáticoSí.Sí.Sí.
PostgreSQL incluidoSí (plugin).Sí (gratis 90 días).No (usar Neon, Supabase).
⭐ Railway para empezar: Para tu primera API de Node.js + PostgreSQL + MongoDB, RECOMIENDO Railway: el plan gratuito es generoso, incluye PostgreSQL y Redis como plugins, y el flujo de deploy es el más simple. Para frontend (React, Vue), Vercel. Para ambos, Render (más versátil pero interfaz menos pulida). Las 3 son buenas: no pierdas tiempo eligiendo, empieza con Railway y migra si necesitas.
🎬
Video del instructor

El administrador aún no ha insertado un video para esta sección.

2.11.2 El flujo completo: de GitHub a producción

El deploy moderno es RIDÍCULAMENTE simple: subes tu código a GitHub, conectas tu repo a una plataforma, y cada vez que hagas push, la plataforma redespliega automáticamente. CI/CD gratis y sin configurar nada.

Paso a paso: tu primer deploy en Railway

  • 1. Sube tu código a GitHub: git init, git add, git commit, git push.
  • 2. Crea cuenta en railway.app con tu GitHub.
  • 3. 'New Project' > 'Deploy from GitHub repo' > selecciona tu repo.
  • 4. Railway detecta automáticamente que es Node.js (gracias al package.json).
  • 5. Configura las variables de entorno: pestaña 'Variables' > agrega las de tu .env (excepto las que ya inyecta Railway).
  • 6. Railway instala dependencias (npm install) y ejecuta 'npm start' automáticamente.
  • 7. En 2-3 minutos, tu API está en producción en una URL tipo https://mi-app.railway.app.
  • 8. Cada push a main redespliega automáticamente. Magia.
⭐ Procfile opcional en Railway: El Procfile es OPCIONAL en Railway. Por defecto, ejecuta 'npm start' que viene de tu package.json. Si tu script de inicio es distinto (ej: 'node dist/server.js' con TypeScript compilado), configúralo en railway.json o Procfile. Si tu app no inicia, los logs de Railway te dicen QUÉ falló: dependencias, puerto, env vars faltantes, etc.
🎬
Video del instructor

El administrador aún no ha insertado un video para esta sección.

2.11.3 Variables de entorno en producción

Las variables de entorno son el mecanismo para configurar tu app según el entorno: desarrollo, staging, producción. En desarrollo las pones en .env (con dotenv); en producción las configuras en la plataforma. NUNCA subas el .env a Git: cada entorno tiene las suyas.

VariableDesarrollo (.env)Producción (Railway)
PORT3000Asignado por Railway (usar process.env.PORT).
MONGODB_URImongodb://localhost:...mongodb+srv://user:pass@cluster.mongodb.net/...
JWT_SECRETmi_secreto_devopenssl rand -hex 64 (largo, aleatorio).
NODE_ENVdevelopmentproduction.
// .env (desarrollo, NUNCA subir a Git)
PORT=3000
MONGODB_URI=mongodb://localhost:27017/mi_app
JWT_SECRET=secreto_para_desarrollo
NODE_ENV=development

// .gitignore (CRÍTICO)
.env
.env.local
.env.production
node_modules/

// config.js: leer variables con validación
import dotenv from 'dotenv';
dotenv.config();  // lee el .env

export const config = {
  port: process.env.PORT || 3000,
  mongoUri: process.env.MONGODB_URI,
  jwtSecret: process.env.JWT_SECRET,
  nodeEnv: process.env.NODE_ENV || 'development',
};

// Validar que las variables críticas existan
if (!config.jwtSecret || config.jwtSecret.length < 32) {
  throw new Error('JWT_SECRET debe existir y tener al menos 32 caracteres');
}

Variables de entorno: .env, .gitignore, config.js

⭐ Secret único por entorno: En producción, NUNCA uses el JWT_SECRET de desarrollo. Genera uno NUEVO y largo con: openssl rand -hex 64. Si tu código de desarrollo se filtra a Git, el secret de producción sigue siendo seguro. La regla: cada entorno tiene su propio secret, generado independientemente. Es una capa más de defensa en profundidad.
🎬
Video del instructor

El administrador aún no ha insertado un video para esta sección.

2.11.4 Dominio personalizado y HTTPS

Tu API empieza en mi-app.railway.app. Para profesionalizar, usas un dominio personalizado: api.mi-dominio.com. Las 3 plataformas (Railway, Render, Vercel) tienen HTTPS automático con Let's Encrypt: tu sitio se sirve por HTTPS sin que tengas que configurar nada.

Cómo configurar un dominio personalizado

  • 1. Compra el dominio en Namecheap, Google Domains, Cloudflare (~$10/año).
  • 2. En tu plataforma (Railway > Settings > Domains), agrega api.mi-dominio.com.
  • 3. La plataforma te da un CNAME: api.mi-dominio.com CNAME mi-app.railway.app.
  • 4. En tu registrador de dominios, configura ese CNAME.
  • 5. Espera 5-30 minutos a que propague el DNS.
  • 6. La plataforma automáticamente emite un certificado Let's Encrypt y activa HTTPS.
  • 7. Configura redirects: HTTP -> HTTPS, www -> sin www (en la plataforma o en Cloudflare).
⭐ Cloudflare es tu CDN/DNS gratis: Cloudflare es tu mejor amigo para dominios: gratis para el plan básico, te da DNS ultrarrápido, caché, protección DDoS, y Analytics. Es el intermediario entre tu dominio y tu plataforma. Configura Cloudflare PRIMERO, después apunta el dominio a tu plataforma. Es el setup profesional estándar.
🎬
Video del instructor

El administrador aún no ha insertado un video para esta sección.

2.11.5 Monitoreo y logs en producción

En producción, necesitas saber si tu API está caída, si tiene errores, y cómo está rindiendo. Las 3 plataformas (Railway, Render, Vercel) te dan logs en tiempo real, métricas básicas (CPU, RAM, requests), y alertas. Para cosas más avanzadas, hay herramientas gratuitas como UptimeRobot (monitoreo 24/7) y Sentry (tracking de errores).

HerramientaPara qué sirveCosto
Logs de Railway/RenderVer requests, errores, y stdout de tu app en tiempo real.Incluido.
UptimeRobotTe avisa si tu API está caída (cada 5 min).Gratis hasta 50 monitores.
SentryTracking de errores: te dice QUÉ error, en QUÉ línea, con qué contexto.Gratis hasta 5,000 eventos/mes.
LogRocket / HotjarGrabaciones de sesiones de usuarios (ver qué hacen).Gratis hasta 1,000 sesiones.
Google AnalyticsTráfico y comportamiento de usuarios.Gratis.
⭐ Sentry en producción es ORO: Sentry es ORO para producción: cuando un usuario reporta 'la app no funciona', Sentry te dice EXACTAMENTE qué error pasó, en qué archivo, con qué datos. Sin Sentry, estás adivinando. Es gratis hasta 5,000 eventos/mes (suficiente para empezar). Integra con 1 línea: import * as Sentry from '@sentry/node'; Sentry.init({ dsn: '...' });. Es la diferencia entre un junior que reza por que la app funcione y un senior que sabe exactamente qué falla.
🎬
Video del instructor

El administrador aún no ha insertado un video para esta sección.

2.11.6 Errores comunes del primer deploy

El primer deploy SIEMPRE tiene errores. Es normal, es humano, y es la mejor forma de aprender. Aquí están los 7 problemas más comunes y cómo solucionarlos en menos de 5 minutos cada uno.

ErrorCausa típicaSolución
'Application failed to start'Script de inicio incorrecto o dependencias faltantes.Verifica que 'npm start' funcione localmente.
'Cannot connect to MongoDB'MONGODB_URI no configurada o BD en otra red.Configura la URI en variables de entorno de la plataforma.
'Port 3000 already in use'Hardcoded port en vez de process.env.PORT.Usa process.env.PORT || 3000.
'JWT must be provided'JWT_SECRET no configurada en producción.Agrega JWT_SECRET a las env vars de la plataforma.
'CORS error' en el frontendEl backend no permite el dominio del frontend.Configura cors({ origin: 'https://mi-frontend.com' }).
404 en todas las rutasSirves el frontend con Express pero la ruta es del backend.Separa frontend y backend en servicios distintos.
App se duerme después de inactividadPlan gratuito duerme servicios sin uso.Upgrade a plan pago, o usa un keep-alive ping (UptimeRobot).
⭐ Logs first, Google second: El 90% de los errores del primer deploy se resuelven mirando los LOGS de la plataforma. Railway, Render, Vercel tienen una pestaña 'Logs' que muestra stdout/stderr de tu app en tiempo real. Si tu app no inicia, el log te dice QUÉ falló. Es tu primera parada de debug, antes de Google, antes de Stack Overflow, antes de rezar. LOGS FIRST.
🎬
Video del instructor

El administrador aún no ha insertado un video para esta sección.

📚 Contenido ampliado

Material adicional, referencias externas verificadas y ejemplos extendidos.

🤖 AI Mission

El primer deploy enseña más que 10 tutoriales. Hazlo.

Misión: Toma tu API de Express + MongoDB del Tema 2.10, súbela a Railway, configura las variables de entorno, y verifica que funcione en producción. Después, configura un dominio personalizado (o un subdominio gratis) y HTTPS. Pídele a la IA que audite tu deploy. Anota en tu cuaderno: ¿qué problemas encontraste? ¿cuánto tardaste en tener la API en producción?

Pasos sugeridos

  1. Asegúrate de que tu API funciona localmente con npm start.
  2. Sube el código a GitHub: git add, commit, push.
  3. Crea cuenta en railway.app con GitHub.
  4. New Project > Deploy from GitHub > selecciona tu repo.
  5. Configura variables de entorno en Railway: MONGODB_URI, JWT_SECRET, NODE_ENV=production.
  6. Espera 2-3 min a que termine el deploy. Railway te da una URL.
  7. Prueba la URL: GET /perfil, POST /login. ¿Funciona?
  8. Si hay errores, ve a la pestaña 'Logs' y léelos.
  9. Configura un monitor en UptimeRobot.com (gratis) para que te avise si la API se cae.
  10. Opcional: configura un dominio personalizado (comprar dominio ~$10, o usar un subdominio gratis con servicios como eu.org).
  11. Pídele a la IA: 'Tengo mi API en Railway. Dame 2 sugerencias de mejora: seguridad, performance, o monitoreo. NO me des código, dime QUÉ agregar.'
  12. Aplica 2 mejoras.
  13. Anota en tu cuaderno: 3 problemas que encontraste, cómo los resolviste, y cuánto tardaste de localhost a producción.

📓 Entregable: URL pública de tu API en Railway, capturas de: pantalla de Railway con el deploy exitoso, logs sin errores, monitor de UptimeRobot activo, y media página de cuaderno con tu reflexión del proceso.

🚫 Errores típicos de razonamiento

Error 1: Subir el archivo .env a Git.
Por qué: .env contiene secretos (JWT_SECRET, MONGODB_URI, API keys). Si lo subes a Git, cualquiera con acceso al repo puede verlos y usarlos. Solución: agregar .env a .gitignore desde el INICIO del proyecto. Si ya lo subiste, hay que ROTAR todos los secretos (cambiar las claves) porque Git guarda el historial.
Error 2: Hardcodear el puerto en lugar de usar process.env.PORT.
Por qué: Las plataformas de deploy (Railway, Render, Heroku) asignan un puerto DINÁMICAMENTE vía la variable de entorno PORT. Si hardcodeas 3000, la plataforma no puede enrutar las peticiones. Usa SIEMPRE: const PORT = process.env.PORT || 3000; Es un error tan común que hay memes sobre él.
Error 3: Confiar solo en los logs de la plataforma sin tener un monitor externo.
Por qué: Si tu API se cae de noche y no la abres, no te enteras hasta que un usuario se queja. Un monitor externo (UptimeRobot, gratis) te avisa por email/Slack cuando tu API está caída. Es la diferencia entre enterarte en minutos vs enterarte en horas.
Error 4: No configurar CORS y que el frontend no se comunique con el backend.
Por qué: Por seguridad, los navegadores bloquean peticiones cross-origin (frontend en un dominio, backend en otro). Si tu frontend está en mi-app.vercel.app y tu backend en api.railway.app, el navegador va a bloquear las peticiones a menos que el backend explícitamente permita ese origen con cors({ origin: 'https://mi-app.vercel.app' }).
Error 5: Usar el mismo JWT_SECRET en desarrollo y producción.
Por qué: Si tu código de desarrollo (con tu secret) se filtra, el atacante puede generar tokens válidos para tu producción. Genera SIEMPRE secrets DIFERENTES por entorno: openssl rand -hex 64 para producción. Es una capa más de defensa en profundidad.

🧪 Laboratorio práctico

El primer deploy es un rito de paso. Hazlo, sufre un poco, y nunca más lo olvidarás.

Laboratorio: Deploy completo de tu API con Railway + UptimeRobot + Sentry

Objetivo: Llevar tu API de Express + MongoDB del Tema 2.10 a producción con Railway, configurar monitoring con UptimeRobot, tracking de errores con Sentry, y un subdominio personalizado (opcional). El resultado: tu API en internet, monitoreada, y con HTTPS.

Pasos

  1. Parte del proyecto 'api-libros-mongo' del Tema 2.10.
  2. Verifica que .env NO está en Git, pero .env.example SÍ (con placeholders).
  3. Verifica que el script 'start' funciona: npm start debe arrancar la app.
  4. Sube a GitHub: git add, commit, push.
  5. Crea cuenta en railway.app con GitHub.
  6. New Project > Deploy from GitHub > selecciona tu repo.
  7. Configura variables: MONGODB_URI, JWT_SECRET, NODE_ENV=production.
  8. Espera 2-3 min. Verifica que la URL de Railway responde.
  9. Ve a la pestaña Logs: ¿hay errores? Corrígelos.
  10. Crea cuenta en sentry.io (gratis). Crea un proyecto Node.js.
  11. Instala: npm install @sentry/node. Agrega Sentry.init() en server.js.
  12. Configura la DSN de Sentry como variable de entorno en Railway.
  13. Prueba: tira tu app a propósito (throw new Error('test')). Verifica que Sentry captura el error.
  14. Crea cuenta en uptimerobot.com. Agrega un monitor HTTP a la URL de Railway cada 5 min.
  15. Comparte la URL con 1 persona y pídele feedback.
  16. Haz commit: 'feat: deploy con Railway, Sentry y UptimeRobot configurados'.
  17. Anota en tu cuaderno: URL pública, problemas encontrados, soluciones, tiempo total de deploy.

📓 Entregable: URL pública de la API en Railway, capturas de: deploy exitoso, dashboard de Sentry con un error capturado, monitor de UptimeRobot activo, y commit en Git.

📓 Tu cuaderno: Anota pseudocódigo, diagramas, errores que encontraste y respuestas a "explica sin código". La escritura manual refuerza tu razonamiento. Tu profesor puede pedirte que subas fotos de páginas específicas.