1. ¿Por qué mi servidor se detiene en cada despliegue?
Al trabajar en proyectos personales, a menudo me topo con entornos con recursos limitados (instancias micro de GCP, Raspberry Pi, etc.). Yo administro varios servidores: desde máquinas de alto rendimiento para inferencia y entrenamiento de IA hasta VMs mínimas que apenas mantienen un servidor de nombres. Especialmente, me gustan las Raspberry Pi 5. No generan una factura eléctrica alta aun funcionando 24 h y su rendimiento me parece sólido. Si los demás servidores se sienten como ganado bajo mi cuidado, ¿la Raspberry Pi será como una mascota que me genera cariño?
Sin embargo, al sobrecargar a esta "mascota" surgió un problema: el CPU llegaba al 100 % durante los despliegues. El culpable era el Celery Worker. Al lanzar simultáneamente los grupos Blue y Green para lograr un despliegue sin downtime, el número de workers se duplicaba y el sistema no podía absorber la carga. Reducir la cantidad de workers degradaba el rendimiento, pero mantenerlos provocaba que el servidor colapsara. Un verdadero dilema.

Para resolverlo, creé un script de despliegue Blue‑Green personalizado que minimiza el consumo de recursos y garantiza estabilidad.
2. Estrategia de solución: ahorrar recursos y aumentar la confiabilidad
Un despliegue Blue‑Green tradicional ejecuta ambos entornos a la vez, pero yo diseñé la siguiente táctica para reducir la carga del CPU:
- Detención preventiva de servicios en segundo plano (Celery): antes de iniciar la nueva versión del servidor web, paro los procesos pesados de la versión anterior (Worker, Beat) para liberar CPU.
- Arranque por etapas: en lugar de lanzar todo simultáneamente, primero levanto
Web + Redisy realizo un health‑check. - Human‑in‑the‑loop: una vez finalizada la automatización, el administrador verifica visualmente y, con su aprobación, elimina la versión antigua.
Al analizar cada caída del servidor, la causa principal era que los workers de Celery se reiniciaban, recibían tareas inmediatamente y consumían CPU al máximo. Disminuir la concurrencia del worker hubiera solucionado el problema, pero penalizaba la velocidad de procesamiento asíncrono durante el despliegue.
Pensé entonces en una solución que mantuviera el cero downtime mientras pausaba temporalmente a los workers de Celery, liberando CPU antes de desplegar el nuevo código.
3. Código esencial
Todo el código está disponible en mi repositorio de GitHub. A continuación, algunos fragmentos clave.
① Aislamiento de proyectos con Docker Compose
Utilizo la opción -p de docker compose para crear dos proyectos (espacios de nombres) llamados blue y green a partir del mismo archivo de configuración.
dc() {
# Asigna dinámicamente el nombre del proyecto (-p) para aislar entornos
docker compose -f "$COMPOSE_FILE" "$@"
}
② Health Check riguroso
No cambias el tráfico hasta confirmar que la nueva versión está completamente operativa.
health_check() {
# Reintenta hasta 10 veces que el puerto responda 200 OK
if curl -fsSIL --max-time "$HEALTH_TIMEOUT" "$url"; then
ok "Health check passed"
return 0
fi
}
③ Recuperación silenciosa en caso de falla
Si la nueva versión presenta problemas, re‑activo inmediatamente los servicios de la versión anterior para que los usuarios no perciban interrupciones.
En lugar de eliminar por completo los workers y beat con rm -f, utilizo stop para liberar CPU y mantener la posibilidad de reintegrarlos rápidamente en caso de emergencia. Así, al ejecutar up -d después de un fallo, los procesos antiguos continúan sin interrupción.
4. Buenas prácticas operativas: la estética de "verificar antes de eliminar"
El script finaliza mostrando un mensaje al administrador en lugar de borrar automáticamente la versión antigua.
"El despliegue se completó con éxito. Por favor, verifica manualmente. Si todo está bien, copia el comando siguiente para limpiar la versión anterior."
Esta simple medida protege contra el 1 % de errores que la automatización podría pasar por alto.
5. Conclusión
Este script encarna la reflexión necesaria para extraer el mayor rendimiento de recursos limitados. Aunque es un código sencillo, lo utilizo a diario y creo que otros desarrolladores con restricciones similares pueden beneficiarse. Espero que sirva a pequeños equipos que enfrentan desafíos parecidos.
Enlaces relacionados:
-
¡Deja tus preguntas en los comentarios o en un Issue de GitHub!
No hay comentarios.