39  N1. Qué es un servidor de verdad

On-premise, datacenters, VPS y bare metal — la máquina siempre existe

NotaEn una frase

“La nube” no existe: son computadoras de otros en datacenters. Este capítulo mapea el espectro completo — tu laptop, un servidor en tu closet (on-premise), un VPS alquilado, bare metal — y qué responsabilidad carga cada uno. Al final vas a conectarte por SSH a una máquina remota y dejar tu app corriendo ahí, como se hizo durante 20 años.

39.1 El problema

“Sube la app a la nube” — ¿a dónde exactamente? Tu API corre en tu laptop porque tu laptop es una computadora encendida con un proceso escuchando en un puerto. Para que otros la usen necesitas otra computadora, encendida 24/7, con una IP pública. Toda la industria del hosting se reduce a: ¿de quién es esa máquina, dónde está, y quién la mantiene?

Una IP es la dirección numérica de una máquina en la red: 203.0.113.10. Los servidores tienen IP pública; dentro de una VPC tienen IPs privadas que internet no ve.

Un puerto es una puerta numerada dentro de una computadora: la IP llega al edificio, el puerto al departamento. :3000 = “la app que escucha en el departamento 3000”. Postgres suele usar 5432, HTTP el 80, HTTPS el 443.

Un proceso es un programa en ejecución: el sistema operativo le da memoria propia y un lugar en la fila del CPU. Tu API es un proceso; Postgres es otro; el navegador es varios. Que “se caiga el proceso” = el programa murió.

39.2 Cómo lo resuelve un equipo

Nadie empieza comprando un rack. El camino típico de un producto:

  1. Desarrollo: tu laptop. IP localhost, apagas cuando quieres.
  2. Primer deploy: un VPS de $5/mes (DigitalOcean, Hetzner). Una porción de máquina ajena con IP pública.
  3. Crecimiento: cloud (AWS/Azure/GCP) — misma idea, más servicios alrededor.
  4. Escala o regulación: datacenter propio o bare metal (máquina física completa alquilada). Raro en productos pequeños.

La nube son computadoras de otro que rentas por hora: AWS, Azure, GCP te prestan máquinas, redes y servicios administrados. Pagas por no comprar hardware — y por no administrarlo tú.

localhost significa “esta misma máquina” — es la dirección que tu computadora usa para hablarse a sí misma. Cuando desarrollas, el “servidor” y el “cliente” viven en tu laptop: por eso todo es localhost:3000.

Un deploy es poner tu código a correr en el servidor: copiar la imagen, iniciar el proceso, verificar que responde. El objetivo es que sea aburrido — automático, repetible, con rollback.

La lección no es “usa X” sino entender qué responsabilidad heredas en cada opción: hardware, red, electricidad, parches del SO, backups.

39.3 Conceptos nuevos

  • U On-premise: tu propio hardware en tu edificio — control total, costo total
  • Ops Colocation: tu máquina vive en un datacenter ajeno (ellos: luz, red, seguridad física)
  • Ops VPS (Virtual Private Server): una porción virtual de máquina física — DigitalOcean, Hetzner, EC2 básico
  • Ops Bare metal: una máquina física completa solo para ti, alquilada
  • U La máquina siempre existe: “serverless” también corre en una — solo que no es tu problema

39.4 La explicación visual

flowchart LR
  A["Tu laptop<br/><i>0 usuarios</i>"] --> B["Servidor en tu closet<br/><i>on-premise</i>"]
  B --> C["VPS<br/><i>porción alquilada</i>"]
  C --> D["Cloud<br/><i>AWS/Azure/GCP</i>"]
  D -.-> E["Bare metal / colo<br/><i>escala extrema</i>"]

Modelo Máquina de… Datacenter de… Tú administras Costo típico
On-premise tuya tuyo (tu closet) TODO Hardware + luz + tu tiempo
Colocation tuya ajeno SO en adelante $100-500/mes por rack
VPS ajena (compartida) ajeno SO en adelante $5-50/mes
Cloud VM ajena ajeno SO en adelante Por hora/segundo
Bare metal ajena (exclusiva) ajeno SO en adelante $100+/mes

La regla de oro: a más control, más responsabilidad. No hay opción “mejor” — hay opción que te cuesta lo que puedes pagar.

39.5 Implementación

El camino clásico que todo backend debería hacer una vez: alquilar un VPS, entrar por SSH y dejar la app corriendo. Aunque luego uses PaaS o serverless, entenderás qué abstraen.

IaaS: rentas la máquina, administras todo lo de adentro. PaaS: rentas la plataforma, solo traes tu código. SaaS: usas el software hecho (Gmail, RDS administrado). Menos control, menos trabajo.

Serverless = no piensas en servidores: subes una función y el proveedor la ejecuta por evento, escalando de 0 a 1000 sola. Pagas por ejecución. Lambda (AWS), Cloud Functions (GCP), Azure Functions.

Paso 1 — provisionar. En DigitalOcean/Hetzner creas un “Droplet”/VPS: Ubuntu, el plan más barato, y subes tu llave SSH pública (la alternativa — password — es la primera mala práctica que evitaremos).

Paso 2 — entrar. SSH es “la terminal de otra máquina”:

# From your terminal — run the remote machine's shell
ssh ubuntu@203.0.113.10
# Now every command runs on THAT machine, not yours

Paso 3 — subir tu app (con git clone o scp/rsync):

# On the VPS: clone and install
git clone https://github.com/you/taskflow.git
cd taskflow && npm ci

Paso 4 — correrla… y que sobreviva. Si la arrancas con node dist/index.js y cierras la terminal, el proceso muere con tu sesión. Necesitas un gestor de procesos — algo que la reinicie si crashea y la arranque si el servidor reinicia:

La terminal (consola, línea de comandos) es la interfaz de texto con el sistema operativo: escribes comandos, lees resultados. Es como hablarle a la computadora por cartas en vez de señalar con el mouse.

# systemd — the OS's own process manager (recommended)
sudo systemctl enable taskflow    # start on boot
sudo systemctl start taskflow
sudo systemctl status taskflow    # is it alive?
journalctl -u taskflow -f         # its logs

# PM2 — same idea, Node-specific and friendlier
pm2 start dist/index.js --name taskflow
pm2 save && pm2 startup           # survive reboots

Paso 5 — abrir el puerto justo. Tu app escucha en 8000, pero el mundo espera HTTP en 80. Además, exponer el puerto de la app directo es mala idea — por eso va nginx delante (reverse proxy, cap. 33). El firewall mínimo:

Un reverse proxy (nginx, ALB, Cloudflare) es el portero: recibe todo el tráfico en el 443, termina TLS y reparte a tu app interna. La app nunca mira a internet directamente — el proxy la protege.

sudo ufw allow OpenSSH   # port 22 — NEVER lock yourself out
sudo ufw allow 'Nginx Full'
sudo ufw enable

Resultado: http://203.0.113.10 responde tu API, corriendo en una máquina que no ves, en un datacenter que no conoces. Eso es “la nube” — con tu responsabilidad encima.

Guíame para desplegar mi API [Express/FastAPI/Go] en un VPS Ubuntu por
primera vez. Dame los pasos en orden: crear la llave SSH si no tengo,
provisionar el VPS, conectar por SSH, subir el código, instalar
dependencias, y dejar el proceso vivo con systemd (con el archivo .service
completo). Requisitos: NO uses password para SSH (solo llaves), crea un
usuario no-root para la app, configura ufw abriendo solo lo necesario, y
explícame por qué cada capa de seguridad existe.

39.6 ¿Por qué cada modelo existe?

Lo único que necesitas llevarte: el espectro mueve una sola variable — quién sufre cuando algo físico se rompe. On-premise: tú, a las 3am, manejando al datacenter. VPS: ellos, tú solo el SO. Todo lo demás (precio, control, compliance) se deriva de esa única pregunta.

Una variable es una caja con nombre donde guardas un valor: let total = 42 guarda el 42 bajo el nombre total. Puedes leerla y cambiarla después (total = 50). const = caja que no se puede reemplazar.

  • On-premise sigue existiendo por tres razones reales: regulación (bancos, salud — el dato no puede salir), costo a escala masiva (Dropbox salió de AWS ahorrando millones), y latencia (fábricas, hospitales sin internet confiable).
  • VPS es el sweet spot de proyectos pequeños: $5/mes, IP propia, aprendes Linux real.
  • Cloud paga cuando necesitas los servicios alrededor de la máquina (redes, balanceadores, servicios administrados — caps. siguientes).
  • Bare metal es para cargas que no toleran la virtualización o la vecindad de otros tenants.

39.7 Errores comunes

Error Por qué pasa Fix
SSH con password y root abierto “Es solo un VPS de prueba” — los bots escanean port 22 en minutos Llaves SSH, PermitRootLogin no, usuario no-root
El proceso muere al cerrar la terminal Lo corriste con node app.js en tu sesión SSH systemd o PM2
Todo el tráfico directo al puerto 8000 “Funciona, no lo toco” ufw + nginx delante; el puerto de la app queda interno
No saber dónde está la máquina La región importa: latencia y leyes del dato Elige región cerca de tus usuarios

39.8 Buenas prácticas

  • Llaves SSH siempre; password nunca. La llave pública va al VPS al crearlo; la privada no sale de tu máquina.
  • Un usuario por servicio, no root. Si tu app se compromete, el atacante hereda los permisos de ese usuario — que sean pocos.

La autorización responde “¿qué puedes hacer?”: eres usuario válido (autenticado), pero ¿puedes borrar esta tarea? Se decide por rol o por ownership — y se verifica en cada request, no se recuerda.

  • Firewall que niega por defecto y abre solo 22/80/443.
  • Documenta la máquina: IP, región, qué corre ahí. Un servidor olvidado es una factura olvidada y un agujero de seguridad.

EXTRA Antes de servidores, los roadmaps piden entender internet misma — cada ítem mapea a un capítulo:

  • ¿Cómo funciona internet? — paquetes que viajan entre IPs
  • ¿Qué es HTTP y HTTPS? — cap-01, cap-33
  • ¿Qué es una dirección IP? — este capítulo
  • ¿Qué es un nombre de dominio? ¿DNS? — cap-33, nu-04
  • ¿Qué es hosting? — nu-02
  • ¿Qué es SMTP? — el protocolo de correo; por eso mandar email es un job externo (cap-21)

39.9 Ejercicio

  1. Ordena estas opciones de menor a mayor responsabilidad tuya: bare metal, PaaS, VPS, on-premise, serverless.
  2. Tu app corre con npm start dentro de tu sesión SSH. Nombra dos formas en que esto falla sin que toques nada.
  3. ¿Por qué el firewall se configura ANTES de exponer la app?
  1. Serverless < PaaS < VPS < bare metal < on-premise. (En serverless ni siquiera ves el SO; en on-premise hasta la electricidad es tuya.)
    1. Tu sesión SSH se cae o la cierras → el proceso muere con ella.
    2. El servidor reinicia por un parche de AWS/DigitalOcean → nada vuelve a arrancar tu app. Ambas se arreglan con un process manager (systemd/PM2).
  2. Porque el orden es defensivo: primero cierras puertas, luego abres la que necesitas. Si expones la app y después configuras el firewall, quedó una ventana donde cualquiera entra — y los bots no esperan.

39.10 Mini reto

Este script de deploy circula por internet. Encuentra las tres decisiones peligrosas:

ssh root@203.0.113.10
git clone https://github.com/you/taskflow.git && cd taskflow
npm install
export DB_PASSWORD="super-secret-prod-pw"
node dist/index.js &
  1. root por SSH — el usuario con todos los permisos expuesto a internet (debería estar PermitRootLogin no + usuario normal).
  2. Secreto en la línea de comandos — export DB_PASSWORD=... queda en el historial del shell y visible en ps mientras corre (cap. 24 y N4 cubren dónde van los secretos de verdad).
  3. node ... & y a rezar — el proceso queda huérfano: muere con la sesión SSH, nadie lo reinicia si crashea, nada lo arranca al reiniciar el servidor. Falta systemd/PM2.

39.11 Vocabulario técnico del capítulo

Una clase es el molde de un objeto: define qué datos y qué métodos tiene. class Task es el molde; new Task() es una instancia concreta. Go no tiene clases — usa struct + métodos sueltos.

Latencia = cuánto tarda UNA operación (ms). Throughput = cuántas haces por segundo. Se pelean: bajar latencia no siempre sube throughput. La latencia la siente el usuario; el throughput lo paga tu factura.

Vertical: máquina más gorda (más CPU/RAM) — fácil, tiene techo. Horizontal: más máquinas — el camino de internet, pero requiere que la app no guarde estado local (por eso todo va a BD/Redis).

Producción (prod) es el entorno real: donde están los usuarios, los datos que importan y las consecuencias. Todo lo demás — local, staging — existe para que los errores ocurran antes de llegar ahí.

Una dependencia es código de terceros que tu proyecto usa: npm install, pip install, go get las traen. Cada una es deuda — ahora funciona, pero hay que mantenerla, actualizarla y confiar en ella.

Un CLI (Command Line Interface) es un programa que se usa escribiendo comandos en la terminal: git, npm, docker son CLIs. Lo contrario es una GUI (interfaz gráfica con botones).

Un log es el diario del programa: qué pasó, cuándo, con qué request. Estructurado = en JSON con campos (request_id, user_id), para filtrar por máquina y no con los ojos.

Un secreto es un dato que no puede publicarse: contraseñas de BD, llaves de API, el secreto que firma los JWT. Viven en .env (fuera de git) o en un secret manager — nunca en el código ni en el repo.

39.12 Lo que deberías saber hacer ahora