Cómo funciona un servidor web (HTTP, peticiones, Apache, Nginx)

Infraestructura web · HTTP · Actualizado 2026 · Lectura: ~12 min

Cada vez que escribes una dirección en tu navegador, como “todoplantas.net”, ocurre una conversación invisible entre tu ordenador y un servidor web en algún lugar del mundo. Ese servidor es un programa que escucha en el puerto 80 (HTTP) o 443 (HTTPS), recibe la petición, busca el archivo solicitado o ejecuta un programa, y devuelve una respuesta (con el contenido HTML, imágenes, CSS, JavaScript). El protocolo HTTP define el formato de ese diálogo: verbos como GET o POST, códigos de estado como 200 OK, 404 Not Found o 500 Internal Server Error. Te explico cómo funciona por dentro un servidor web, las diferencias entre Apache y Nginx, y cómo se procesa una petición PHP o Python.

01 / Definición

¿Qué es un servidor web? Hardware vs software

En el mundo de las redes, “servidor” puede referirse a dos cosas: la máquina física (un ordenador potente con muchos núcleos y RAM) o el software que corre en esa máquina y sirve contenido web. El servidor web es el programa (Apache, Nginx, IIS, Caddy, Lighttpd) que acepta peticiones HTTP de los clientes (navegadores, APIs, bots) y responde con el contenido solicitado (archivos estáticos o respuestas dinámicas).

Componentes clave:

  • Dirección IP y puerto: el servidor web se “enlaza” a una o varias direcciones IP y a un puerto (80 para HTTP, 443 para HTTPS). Escucha permanentemente conexiones TCP entrantes.
  • Directorio raíz (DocumentRoot): carpeta en el sistema de archivos donde residen los archivos públicos del sitio web (index.html, styles.css, etc.).
  • Módulos o extensión: para soportar lenguajes dinámicos (PHP, Python), compresión, seguridad, etc.
  • Archivos de configuración: definen reglas de reescritura de URL, autenticación, virtual hosts, redirecciones, etc.

El hardware subyacente puede ser un servidor dedicado (físico) en un centro de datos, una máquina virtual en la nube (AWS EC2, Google Compute Engine), o incluso un ordenador de escritorio (para pruebas locales). En producción, se usan servidores robustos con muchas CPUs, RAM y almacenamiento rápido (SSD).

Virtual Hosting (alojamiento virtual)

Un mismo servidor web puede alojar múltiples sitios web en la misma IP gracias a los “virtual hosts” (Apache) o “server blocks” (Nginx). El servidor identifica qué sitio se está pidiendo por el nombre de dominio en la cabecera “Host” de la petición. Por eso puedes tener todoplantas.net y otrodominio.com en el mismo servidor.


02 / Protocolo HTTP

Protocolo HTTP: peticiones GET y POST, cabeceras, cuerpo

HTTP (HyperText Transfer Protocol) es un protocolo de capa de aplicación basado en TCP/IP. Funciona con un modelo petición-respuesta. El cliente (navegador) envía una petición al servidor; el servidor envía una respuesta. Todo el intercambio es texto plano (aunque HTTPS lo cifra).

Una petición HTTP típica (versión 1.1) tiene este formato:

GET /carpeta/archivo.html HTTP/1.1
Host: www.todoplantas.net
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...
Accept: text/html,application/xhtml+xml,...
Accept-Language: es-ES,es;q=0.9
Connection: keep-alive
(una línea en blanco)

El método más común es GET (solicitar un recurso). También existe POST (enviar datos al servidor, por ejemplo, desde un formulario), PUT, DELETE, etc. La línea de petición incluye: método, ruta y versión HTTP. Las cabeceras (Host, User-Agent, Accept, etc.) proporcionan metadatos. Si la petición lleva datos (POST), después de la línea en blanco viene el cuerpo (body).

Ejemplo de respuesta HTTP:

HTTP/1.1 200 OK
Date: Mon, 28 Apr 2025 10:00:00 GMT
Server: Apache/2.4.41 (Ubuntu)
Content-Type: text/html; charset=utf-8
Content-Length: 1234
(una línea en blanco)
<!DOCTYPE html>...

La respuesta también tiene una línea de estado con código y frase (200 OK), cabeceras, cuerpo HTML (o contenido binario).


03 / Códigos de estado

Códigos de estado HTTP: 200, 301, 404, 500 y sus familias

Los códigos de estado indican el resultado de la petición. Se agrupan en familias:

  • 1xx (Informativo): raramente vistos por el usuario (100 Continue).
  • 2xx (Éxito): 200 OK (petición exitosa), 201 Created (recurso creado), 204 No Content (sin cuerpo).
  • 3xx (Redirección): 301 Moved Permanently (redirección permanente), 302 Found (temporal), 304 Not Modified (caché válida).
  • 4xx (Error del cliente): 400 Bad Request (petición mal formada), 403 Forbidden (acceso denegado), 404 Not Found (recurso no existe), 429 Too Many Requests (límite de tasa).
  • 5xx (Error del servidor): 500 Internal Server Error (ej. fallo de script), 502 Bad Gateway (servidor upstream falló), 503 Service Unavailable (sobrecarga o mantenimiento).

Los servidores web pueden configurar páginas de error personalizadas (p.ej. una página HTML amigable para 404).


04 / Apache HTTP Server

Apache HTTP Server: el servidor modular que dominó la web

Apache, lanzado en 1995, es el servidor web más popular durante décadas (aunque desde ~2016 Nginx superó Apache en número de sitios activos). Su arquitectura se basa en procesos o hilos: cada conexión entrante recibe un proceso hijo o un hilo (modelo MPM: prefork (procesos), worker (híbrido), event).

Apache es altamente configurable mediante módulos dinámicos que se cargan en tiempo real en httpd.conf o .htaccess. Módulos comunes:

  • mod_rewrite: reglas de reescritura de URL (para crear URLs amigables).
  • mod_proxy: actuar como proxy inverso o forward.
  • mod_ssl: habilitar HTTPS con OpenSSL.
  • mod_php (o PHP-FPM): procesar scripts PHP.
  • mod_security: firewall de aplicaciones web.

Ventajas de Apache: flexibilidad, soporte masivo de documentación, .htaccess (permite cambios por directorio sin reiniciar). Desventaja: consumo de memoria por cada proceso, lo que limita el número de conexiones simultáneas (muchos procesos pesados).

Apache se utiliza a menudo con un proxy detrás de Nginx (Nginx como frontend que maneja las conexiones y Apache procesa el contenido dinámico).


05 / Nginx

Nginx: arquitectura asíncrona y alto rendimiento para miles de conexiones

Nginx (pronunciado “Engine X”) fue creado por Igor Sysoev en 2004 para resolver el problema C10K (manejar 10.000 conexiones simultáneas). Su arquitectura es asíncrona, manejada por eventos (similar a Node.js). En lugar de un proceso por conexión, Nginx usa un número fijo de trabajadores (workers), cada uno usando un bucle de eventos que atiende muchas conexiones concurrentes de manera no bloqueante. Esto hace que consuma muy poca memoria incluso con decenas de miles de conexiones.

Nginx es ideal para servir archivos estáticos (HTML, CSS, JS, imágenes) y como proxy inverso (balanceador de carga) ante servidores de aplicaciones (Apache, Gunicorn, Node.js, PHP-FPM). También funciona como load balancer, cache de contenidos (caché de respuestas), y TLS terminator.

Configuración típica en Nginx (/etc/nginx/nginx.conf y bloques server). Soporta reescritura, autenticación básica, limitación de tasa, etc. No permite .htaccess (toda la configuración está en archivos centrales), pero ofrece muy alto rendimiento.

Otros servidores menos comunes: Lighttpd (similar a Nginx), Caddy (con HTTPS automático), IIS (de Microsoft, para .NET), OpenLiteSpeed.

Proxy inverso: ¿qué es y para qué sirve?

Un proxy inverso es un servidor que está delante de otros servidores. El cliente se conecta al proxy, este reenvía la petición al servidor de backend (Tomcat, Express, Gunicorn, etc.), obtiene la respuesta y la devuelve al cliente. Beneficios: balanceo de carga, terminar conexiones TLS, caché, compresión, ocultar la infraestructura interna. Nginx es excelente para esto.


06 / Flujo de petición

Flujo de una petición: desde el socket hasta la respuesta

Vamos a ver paso a paso qué sucede dentro cuando un servidor web recibe una petición:

1
Establecimiento de conexión TCP El navegador realiza un DNS para resolver el nombre de dominio a una IP. Abre un socket TCP al puerto 80 o 443. El servidor acepta la conexión (llamada accept()).
2
Lectura de la petición El servidor web lee el flujo de datos (recv()) hasta encontrar el final de la cabecera (doble CRLF). Parsea la línea de petición y las cabeceras.
3
Determinación del recurso solicitado Se extrae la ruta URL (por ejemplo, “/blog/articulo”). El servidor aplica reglas de localización (location en Nginx, Directory en Apache) y reescritura. Identifica el virtual host por la cabecera Host.
4
Comprobaciones de seguridad y métodos Verifica autenticación (si está configurada), límite de tasa, permisos de acceso por IP, etc.
5
Generación de la respuesta (estático o dinámico) Si el recurso es un archivo estático (.html, .css, .jpg) y existe, el servidor lee el archivo del disco y arma la respuesta (cabeceras Content-Type, Content-Length). Si es dinámico (PHP, Python, etc.), el servidor web pasa la petición a un manejador (PHP-FPM, uWSGI, etc.) que ejecuta el script y produce la salida.
6
Envío de la respuesta El servidor web escribe la cabecera de respuesta y el cuerpo a través del socket (send()). Cierra la conexión o la mantiene si se usa keep-alive.

El servidor web también registra la transacción en un archivo log (access.log) y si hubo errores, en error.log.


07 / Servidores dinámicos

Servidores dinámicos: CGI, PHP-FPM, WSGI, y cómo se conectan con Apache/Nginx

Para generar contenido dinámico (PHP, Python, Ruby, Node.js), el servidor web necesita comunicarse con un intérprete o un proceso externo. Los mecanismos más usados:

  • CGI (Common Gateway Interface): antiguo, el servidor web lanza un proceso por cada petición, lo que es muy ineficiente. Hoy casi no se usa.
  • PHP-FPM (FastCGI Process Manager): protocolo FastCGI. Un proceso permanente (pool de trabajadores) escucha en un socket Unix o TCP. Apache mediante mod_proxy_fcgi o Nginx con fastcgi_pass envían la petición a PHP-FPM. PHP-FPM ejecuta el script y devuelve la salida. Es eficiente y soporta opcache.
  • WSGI (Web Server Gateway Interface) en Python: aplicaciones Python (Django, Flask) se ejecutan con servidores WSGI como Gunicorn, uWSGI o mod_wsgi. Nginx/Apache hacen proxy a Gunicorn (socket).
  • Proxy inverso a Node.js: Nginx redirige las solicitudes de una ubicación específica (ej. /api) al puerto donde escucha Node.js (Express), que genera la respuesta.

Ejemplo de configuración Nginx con PHP-FPM:

location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
}

Para Python (Gunicorn):

location / {
    proxy_pass http://localhost:8000;
    proxy_set_header Host $host;
}

08 / FAQ

Preguntas frecuentes sobre servidores web

¿Qué es un servidor web y un servidor de aplicaciones? ¿Son lo mismo?
No. Un servidor web (Apache, Nginx) sirve contenido estático y puede hacer de proxy para aplicaciones. Un servidor de aplicaciones (Tomcat, JBoss, GlassFish) ejecuta aplicación Java EE; incluye un contenedor de servlets, EJB, etc. A menudo se combinan: Nginx sirve estáticos y balancea hacia Tomcat. En Python, el servidor de aplicaciones es Gunicorn/uWSGI.
¿Cómo puedo saber qué servidor web usa un sitio web?
Puedes usar la consola de desarrollador del navegador (pestaña Network, buscar la cabecera “Server”). O herramientas online como Wappalyzer. La cabecera Server puede estar oculta o personalizada por seguridad. Algunos sitios la eliminan intencionadamente.
¿Puedo tener Apache y Nginx en el mismo servidor?
Sí, y es una configuración común: Nginx escucha en el puerto 80/443 como proxy inverso, y Apache escucha en el puerto 8080 (loopback). Así se aprovecha el rendimiento de Nginx para archivos estáticos y conexiones concurrentes, y Apache para la lógica de proceso (si tienes aplicaciones complejas).
¿Qué es un load balancer (balanceador de carga)?
Es un servidor (puede ser Nginx, HAProxy, un hardware dedicado) que distribuye las peticiones entrantes entre varios servidores web (backends) para repartir la carga y proporcionar alta disponibilidad. Evita que un servidor se sobrecargue y si uno falla, redirige el tráfico a los demás.
¿Cómo afecta la configuración de keep-alive al rendimiento?
Keep-alive permite reutilizar la misma conexión TCP para múltiples peticiones (los recursos de una página HTML, CSS, JS, imágenes). Reduce la sobrecarga de establecer nuevas conexiones (handshake TCP/TLS), mejorando el rendimiento. Pero mantener conexiones abiertas consume recursos en el servidor; un valor alto de timeout puede ocupar sockets sin actividad. El equilibrio es clave.

Sigue aprendiendo sobre tecnología

Fuentes y referencias técnicas

Fielding, R., et al. (1999). Hypertext Transfer Protocol – HTTP/1.1 (RFC 2616, obsoleted but still reference).
The Apache Software Foundation. (2024). Apache HTTP Server Version 2.4 Documentation.
Nginx, Inc. (2025). Nginx Documentation: Admin Guide.
Klein, D., & Manoel, F. (2020). Web Servers: Apache vs Nginx – Performance Analysis.
MDN Web Docs. (2025). HTTP Messages.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Scroll al inicio