Tema
PaaS: Vercel, Netlify y más
No todos los proyectos necesitan que administres un servidor. Las plataformas PaaS (Platform as a Service) toman tu repositorio de GitHub, lo compilan y lo publican con HTTPS, CDN global y vistas previas por cada rama, en minutos y muchas veces gratis. En esta lección conocerás las principales y sabrás cuándo conviene usarlas en lugar de un VPS.
Concepto
El flujo es siempre parecido:
txt
git push ──► La plataforma detecta el cambio ──► npm ci && npm run build
│
┌───────────────────────────┴──────────────┐
▼ ▼
Rama main → producción Otra rama / PR → URL de vista previa
(tudominio.com) (mi-proyecto-git-feature.vercel.app)Tú solo configuras: comando de build, carpeta de salida, variables de entorno y dominio.
Los planes cambian
Las capas gratuitas, límites y precios de estas plataformas cambian con frecuencia. Antes de recomendar una a un cliente, revisa los planes vigentes en su sitio oficial y lee los términos de uso comercial (por ejemplo, el plan Hobby de Vercel es para uso personal, no comercial).
Vercel
Creadores de Next.js. Excelente para Next.js, React, Vue, Svelte, Astro, VitePress y funciones serverless.
Paso a paso
- Entra a vercel.com con tu cuenta de GitHub.
- Add New → Project → importa tu repositorio.
- Vercel detecta el framework. Para VitePress ajusta:
- Build Command:
npm run docs:build - Output Directory:
docs/.vitepress/dist
- Build Command:
- Agrega variables de entorno (Settings → Environment Variables), separadas por entorno: Production, Preview, Development.
- Deploy. En segundos tendrás
mi-proyecto.vercel.app. - Settings → Domains → agrega tu dominio y crea los registros DNS que te indique.
vercel.json
Configuración opcional en la raíz del repo:
json
{
"cleanUrls": true,
"trailingSlash": false,
"redirects": [
{ "source": "/blog-viejo/:slug", "destination": "/blog/:slug", "permanent": true }
],
"headers": [
{
"source": "/assets/(.*)",
"headers": [{ "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }]
}
]
}Para una SPA (React/Vite) que necesita fallback a index.html:
json
{
"rewrites": [{ "source": "/(.*)", "destination": "/index.html" }]
}Funciones serverless en Vercel
Un archivo en api/ se convierte en un endpoint (proyectos que no son Next.js):
js
// api/contacto.js → https://tusitio.vercel.app/api/contacto
export default async function handler(req, res) {
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Método no permitido' });
}
const { nombre, correo, mensaje } = req.body || {};
if (!nombre || !correo || !mensaje) {
return res.status(400).json({ error: 'Faltan datos' });
}
// Aquí enviarías el correo con un servicio como Resend, Brevo o SendGrid
return res.status(200).json({ ok: true });
}Netlify
Pionera del "Jamstack". Muy buena para sitios estáticos, con extras como formularios sin backend y redirecciones potentes.
netlify.toml
ini
# netlify.toml (formato TOML) en la raíz del repo
[build]
command = "npm run docs:build"
publish = "docs/.vitepress/dist"
[build.environment]
NODE_VERSION = "22"
# Redirección permanente
[[redirects]]
from = "/contacto.html"
to = "/contacto"
status = 301
# Fallback para SPA (React/Vue con router)
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
[[headers]]
for = "/assets/*"
[headers.values]
Cache-Control = "public, max-age=31536000, immutable"Ojo con el fallback SPA
La regla /* → /index.html con status 200 es solo para SPAs. No la pongas en un sitio VitePress o multipágina, porque las páginas inexistentes devolverían el inicio en lugar de un 404.
Formularios de Netlify
Agrega el atributo data-netlify="true" a tu formulario y Netlify guarda los envíos (y te avisa por correo) sin escribir backend:
html
<form name="contacto" method="POST" data-netlify="true">
<input type="hidden" name="form-name" value="contacto">
<label>Nombre <input type="text" name="nombre" required></label>
<label>Correo <input type="email" name="correo" required></label>
<label>Mensaje <textarea name="mensaje" required></textarea></label>
<button type="submit">Enviar</button>
</form>Cloudflare Pages
Sitios estáticos sobre la red de Cloudflare, con ancho de banda muy generoso y Pages Functions / Workers para lógica en el borde. Si el dominio ya está en Cloudflare, conectar es inmediato. Configuración: comando de build y carpeta de salida, igual que en Vercel/Netlify.
GitHub Pages
Gratis para sitios estáticos directamente desde tu repositorio. Ideal para portafolios, documentación y demos. Lo configuramos con Actions en CI/CD con GitHub Actions. No ejecuta código de servidor.
Render
PaaS para backends: servicios web (Node, Python, PHP con Docker, Go), sitios estáticos, PostgreSQL administrado, Redis, cron jobs y workers.
Pasos para una API Node
- New → Web Service → conecta el repo.
- Runtime: Node. Build Command:
npm ci. Start Command:node src/server.js. - Variables de entorno (
DATABASE_URL, etc.). - Tu app debe escuchar en el puerto de la variable
PORTque Render asigna:
js
const PORT = process.env.PORT || 3000;
app.listen(PORT, '0.0.0.0', () => console.log(`Escuchando en ${PORT}`));render.yaml (infraestructura como código)
yaml
# render.yaml — define servicios y base de datos en el repo
services:
- type: web
name: api-tienda
runtime: node
plan: free
buildCommand: npm ci
startCommand: node src/server.js
healthCheckPath: /api/salud
envVars:
- key: NODE_ENV
value: production
- key: DATABASE_URL
fromDatabase:
name: tienda-db
property: connectionString
databases:
- name: tienda-db
plan: freeServicios gratuitos que se duermen
En las capas gratuitas de varios PaaS de backend, el servicio se "duerme" tras un rato sin tráfico y la primera petición tarda varios segundos en despertar. Para un cliente real usa un plan de pago.
Railway
Interfaz muy amigable: despliegas un repo y agregas una base de datos (PostgreSQL, MySQL, MongoDB, Redis) con un clic; las variables de conexión se inyectan solas. Detecta el lenguaje automáticamente (o usa tu Dockerfile). Cobra por uso de recursos.
Fly.io
Ejecuta tus contenedores Docker en servidores cercanos a tus usuarios en muchas regiones. Se maneja con su CLI (fly launch, fly deploy). Más técnico, muy flexible.
Bases de datos administradas
Si tu frontend vive en un PaaS, la base de datos también puede ser un servicio administrado:
| Servicio | Tipo | Notas |
|---|---|---|
| Supabase | PostgreSQL + auth + storage + APIs | "Firebase open source"; ideal para prototipos y apps completas. |
| Neon | PostgreSQL serverless | Ramas de base de datos, escala a cero. |
| MongoDB Atlas | MongoDB | Capa gratuita para aprender y prototipos. |
| Turso | SQLite distribuido (libSQL) | Muy ligero, ideal para el borde. |
| Upstash | Redis / colas serverless | Pago por petición. |
| Firebase | NoSQL (Firestore) + auth + hosting | Ecosistema de Google. |
Tabla comparativa
| Plataforma | Mejor para | Backend | Base de datos | Dificultad |
|---|---|---|---|---|
| Vercel | Next.js, frontends | Funciones serverless | Integraciones (Neon, Supabase…) | Muy fácil |
| Netlify | Estáticos, Jamstack | Funciones serverless | Integraciones | Muy fácil |
| Cloudflare Pages | Estáticos con mucho tráfico | Workers | D1, KV | Fácil |
| GitHub Pages | Portafolios y docs | No | No | Muy fácil |
| Render | APIs y apps completas | Sí (servicios) | PostgreSQL, Redis | Fácil |
| Railway | Prototipos full-stack | Sí | Varias con un clic | Muy fácil |
| Fly.io | Contenedores globales | Sí (Docker) | Postgres, volúmenes | Media |
¿PaaS o VPS?
Elige PaaS cuando:
- Es un frontend o sitio estático.
- Quieres vistas previas por rama para que el cliente revise.
- No habrá nadie dando mantenimiento al servidor.
- El tráfico es moderado y el presupuesto encaja.
Elige VPS cuando:
- Necesitas procesos largos, websockets intensivos, colas, cron complejos.
- Alojas varios proyectos de clientes y quieres costos fijos.
- Requieres software específico (ffmpeg, LibreOffice, extensiones raras de PHP).
- El costo del PaaS crecería mucho con el tráfico.
Combinación ganadora
Muy común en la industria: frontend en Vercel/Netlify + API y base de datos en un VPS o en Render/Railway. Cada pieza en el lugar donde mejor funciona.
Ejercicios
- Escribe un
netlify.tomlpara una app Vite + React (salidadist, Node 22, fallback SPA). - ¿Qué debes cambiar en una app Express para que funcione en Render?
- Un cliente quiere una landing con formulario de contacto, sin backend ni costo de servidor. ¿Qué propones?
Ver solución
ini
[build]
command = "npm run build"
publish = "dist"
[build.environment]
NODE_VERSION = "22"
[[redirects]]
from = "/*"
to = "/index.html"
status = 200- Escuchar en
process.env.PORT(y en0.0.0.0), definir build/start commands y mover secretos a variables de entorno. - Netlify con Netlify Forms, o Vercel/Cloudflare Pages con una función serverless que envíe el correo mediante un servicio transaccional. Dominio del cliente conectado y HTTPS automático.
Resumen
- PaaS = conectas el repo y la plataforma compila, publica y pone HTTPS.
- Vercel y Netlify para frontends; Render, Railway y Fly.io para backends.
- Configura build, carpeta de salida, variables y dominio; usa archivos como
vercel.json,netlify.toml,render.yaml. - Revisa siempre los planes vigentes y su uso comercial.
- Siguiente: Monitoreo, logs y respaldos.