Cuando un segundo de inactividad cuesta una fortuna
\n\nImagina: estás actualizando una tienda online en PHP, subes la nueva versión por FTP y, de repente, el sitio se cae durante 5 minutos. Cinco minutos son 300 segundos. En ese tiempo, 100 clientes potenciales se van a la competencia, y pierdes no solo dinero, sino también reputación. ¿Te suena familiar?
\n\nEn el mundo actual, donde los usuarios no perdonan errores, el despliegue zero-downtime en PHP no es un lujo, sino una necesidad. Pero, ¿cómo lograr una actualización sin interrupciones si tu stack es PHP, Nginx y varios servidores? Vamos a descubrirlo con ejemplos reales.
\n\n¿Por qué PHP es más complejo de lo que parece?
\n\nA diferencia de Node.js o Python, PHP no soporta el multihilo en el sentido clásico. Cada solicitud es manejada por un proceso independiente de PHP-FPM. Esto impone limitaciones: no puedes simplemente «recargar» el código sin perder las sesiones activas. Sin embargo, esta misma característica nos da un superpoder: la capacidad de redirigir el tráfico entre versiones de forma gradual.
\n\nLos problemas principales al desplegar PHP son:
\n- \n
- Conexiones interrumpidas — el usuario pierde datos de formularios o su sesión \n
- Caché obsoleto — el código antiguo devuelve datos de una caché desactualizada \n
- Migraciones fallidas — la nueva versión de la BD no es compatible con el código anterior \n
Para evitar estos tropiezos, usamos estrategias probadas. Y sí, el despliegue zero-downtime no es magia, es un plan bien definido.
\n\nEstrategia n.º 1: Blue-Green Deployment
\n\nLa forma más fiable es tener dos copias completas de la aplicación: la «azul» (actual) y la «verde» (nueva). Nginx actúa como balanceador de carga.
\n\nCómo se ve en la práctica
\nSupongamos que tienes dos servidores: app1.example.com (blue) y app2.example.com (green). Ambos ejecutan PHP-FPM. Actualmente, el blue está activo. Despliegas la nueva versión en green, la pruebas y luego cambias Nginx para que apunte a green.
Ejemplo de configuración de Nginx para el cambio:
\n\n# nginx.conf\nupstream php_backend {\n # Primero, blue activo\n server app1.example.com:9000 weight=1; # blue\n server app2.example.com:9000 weight=0; # green (desactivado)\n}\n\nserver {\n listen 80;\n server_name mishop.com;\n\n location ~ \\.php$ {\n fastcgi_pass php_backend;\n include fastcgi_params;\n fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;\n }\n}\n\n\nDespués del despliegue en green, cambiamos los pesos:
\n\n# Tras el despliegue — redirigimos el tráfico\nupstream php_backend {\n server app1.example.com:9000 weight=0; # blue (desactivado)\n server app2.example.com:9000 weight=1; # green (activo)\n}\n\n\nRecargamos Nginx sin caídas: nginx -s reload. Todas las conexiones actuales finalizan correctamente, y las nuevas van a green. ¡Despliegue zero-downtime en PHP asegurado!
Ventajas y desventajas
\nVentajas: tolerancia a fallos total, posibilidad de revertir rápidamente (solo restaurando los pesos).
\nDesventajas: requiere el doble de recursos (servidores o contenedores).
Estrategia n.º 2: Rolling Update (actualización progresiva)
\n\nSi tu presupuesto es limitado, usa rolling update. La idea: actualizar los servidores PHP de uno en uno, sin apagar los demás. Los usuarios no notan la interrupción, ya que Nginx redirige las solicitudes a los servidores activos.
\n\nImplementación con PHP-FPM
\nSupongamos que tienes 3 servidores con PHP-FPM. Los sacamos de la rotación uno por uno, actualizamos el código y los devolvemos al grupo.
\n\nPaso 1: Desconectamos el servidor del balanceador (graceful shutdown):
\n\n# En el servidor que vamos a actualizar\nsudo systemctl stop php8.1-fpm\n# Nginx dejará de enviar solicitudes a este servidor automáticamente al no estar disponible\n\n\nPaso 2: Actualizamos el código (mediante git pull, rsync o Docker).
\n\nPaso 3: Reiniciamos PHP-FPM:
\n\nsudo