Ir al contenido

Desplegar Laravel usted mismo, sin los dos minutos de caída

Una plataforma gestionada, un servicio de aprovisionamiento o un servidor pelado - y las cuatro cosas que deciden si un despliegue es invisible. Ninguna de ellas es la elección de alojamiento.

5 min de lectura

Hay tres formas razonables de ejecutar una aplicación Laravel, y la discusión sobre cuál suele tapar que el script de despliegue importa más que la elección.

Las tres opciones, honestamente

Una plataforma gestionada. Usted hace push, ella compila y ejecuta. El menor trabajo operativo disponible, al mayor precio por unidad, con las restricciones de la plataforma como sus restricciones. Buena para un equipo sin capacidad de operaciones y una carga que encaje.

Un servicio de aprovisionamiento sobre sus propios servidores. Algo que configura un servidor que es suyo y le da despliegues, certificados y workers sin que usted escriba el Ansible. Aquí es donde vive la mayoría de las aplicaciones Laravel y es un valor por defecto sensato: se queda la máquina, se ahorra la instalación.

Un servidor pelado que configura usted. Lo más barato, el mayor control, y solo es barato si alguien lo posee. Actualizaciones, certificados, copias, monitorización: la factura es pequeña y la responsabilidad no.

Aquí no hay respuesta equivocada. Solo hay una sin dueño.

Qué decide de verdad si un despliegue duele

1. Entregas atómicas. Despliegue en un directorio nuevo y mueva un enlace simbólico cuando esté listo. Copiar ficheros sobre una aplicación en marcha significa que durante unos segundos las peticiones las sirve una base de código a medio actualizar, lo que produce errores que después nadie reproduce.

releases/2026-09-21-140233/
current -> releases/2026-09-21-140233

Compartido entre entregas: storage/ y el .env. Todo lo demás es nuevo cada vez, y volver atrás es mover el enlace.

2. La reconstrucción de cachés, en orden.

php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan event:cache

Ejecútelas en la entrega nueva antes de que pase a ser la actual. En particular config:cache significa que env() devuelve null en todas partes fuera de los ficheros de configuración, lo cual es el comportamiento correcto y sorprende a la gente: mantenga env() solo en ficheros de configuración.

3. Reiniciar los workers de cola. El paso que más falta:

php artisan queue:restart

Un worker arranca su aplicación una vez y se la queda. Sin esto, su capa web ejecuta la entrega nueva y su capa de colas ejecuta lo que fuera actual la última vez que esos procesos arrancaron, que es su propia clase de fallo.

4. Migraciones, separadas por riesgo. Las rutinarias en el despliegue. Todo lo que reescriba una tabla grande, ejecutado a propósito y vigilado, porque el bloqueo dura más que el tiempo de espera y el despliegue informará de éxito mientras el sitio devuelve errores.

El orden que mantiene el sitio en pie

# en el directorio de la entrega nueva, antes de que esté viva
composer install --no-dev --optimize-autoloader
npm ci && npm run build
php artisan config:cache && php artisan route:cache && php artisan view:cache
 
# hacerla actual
ln -sfn "$RELEASE" current
 
# después
php artisan migrate --force
php artisan queue:restart
sudo systemctl reload php8.3-fpm

Recargar en lugar de reiniciar, para que las peticiones en vuelo terminen. Y comprobar después en lugar de fiarse del script:

ps -eo lstart,cmd | grep "[q]ueue:work"

Horas de arranque anteriores al despliegue significan que el reinicio no les llegó.

Las piezas que la gente no llega a montar

El planificador necesita una entrada de cron, y solo una, en una máquina:

* * * * * cd /var/www/app && php artisan schedule:run >> /dev/null 2>&1

Dos servidores ejecutándola significa que cada tarea programada corre dos veces.

Los workers necesitan un supervisor. queue:restart para workers; no los arranca. Sin systemd o Supervisor vigilando, un despliegue le deja en silencio sin ninguno y los trabajos se amontonan hasta que alguien se fija.

Las copias de seguridad necesitan una restauración. Una copia que nunca se ha restaurado es una hipótesis. Restaure una en un entorno de prueba, con regularidad, y anote cuánto tardó: ese número es su tiempo real de recuperación.

Los registros necesitan un destino. El fichero diario por defecto en el servidor de aplicación vale hasta que tiene dos servidores, momento en el que un incidente significa leer dos conjuntos de ficheros a mano.

La parte que no va de alojamiento

Nada de lo anterior depende de cuál de las tres opciones eligió. Una plataforma gestionada le resuelve parte; un servidor pelado significa que lo escribe una vez. De una forma u otra, el despliegue reinicia los workers o no lo hace.

Por eso lo más útil que puede hacer con este artículo no es cambiar de alojamiento. Es leer su propio script de despliegue y encontrar cuál de estos cuatro pasos falta; en nuestra experiencia suele ser el reinicio de los workers, y falta desde el día en que se escribió el script.

Preguntas relacionadas

¿Un VPS pelado es mala idea?
No, y para una sola aplicación suele ser lo más barato que funciona bien. Lo que lo convierte en mala idea es que no lo posea nadie: actualizaciones de seguridad, renovación de certificados, copias de seguridad que se hayan restaurado al menos una vez. Ese es el coste corriente, no la factura mensual.
¿Las migraciones deberían correr automáticamente en el despliegue?
Las rutinarias sí, porque un paso manual es un paso que alguien acaba olvidando. La excepción es todo lo que reescriba una tabla grande, que quiere ejecutarse a propósito y vigilado, y separado del despliegue que depende de ello.
¿Necesitamos contenedores?
Solo si tiene un motivo. Los contenedores resuelven la deriva de entornos entre varios servicios y varias máquinas; para una aplicación Laravel en un servidor añaden una tubería de compilación y un registro que mantener. Adóptelos cuando el problema que resuelven sea uno que de verdad tiene.
¿Cuál es el paso que más se olvida?
Reiniciar los workers de cola. Un worker sostiene el código con el que arrancó, así que un despliegue que no los reinicie deja media aplicación ejecutando la entrega de la semana pasada, y los fallos resultantes parecen intermitentes e irreproducibles.

← Volver a todos los artículos

Llamar+1 848 272 7583WhatsApp+90 850 308 5436Correoinfo@codefacture.comPágina de contacto