## 1. Why Does My Server Stall Every Time I Deploy? {#sec-38722ba6963c} When running personal projects, you often end up on modest hardware—think GCP’s tiniest instances or a Raspberry Pi. I juggle a fleet of machines, from beefy AI inference servers to a VM that barely keeps a name server alive. I’m especially fond of the Raspberry Pi 5: it runs 24/7 with negligible electricity cost and offers solid performance. If other servers feel like livestock you have to manage, the Pi feels more like a beloved pet. But overloading this little companion caused the CPU to hit 100 % during deployments, thanks to the Celery workers. When I launched both the Blue and Green environments for a zero‑downtime rollout, the number of workers doubled instantly, overwhelming the system. Reducing the worker count slowed processing, while keeping them all caused the server to crash—a classic catch‑22. ![Illustration of an automation script for low‑spec PCs](/media/editor_temp/6/feadd998-56ed-4ccb-9fca-acbb54ef62f2.png) To solve this, I built a **custom Blue‑Green deployment script** that minimizes resource usage while preserving stability. --- ## 2. Strategy: Conserve Resources, Boost Reliability {#sec-8a0968648102} A vanilla Blue‑Green deployment runs both environments side‑by‑side, but I needed to keep CPU load low. My approach: 1. **Pre‑emptively stop background services (Celery):** Before the new web server starts, shut down the heavy background tasks (workers, beat) from the old version to free up CPU. 2. **Staged startup:** Bring up only `Web + Redis` first, run health checks, and only then launch the rest. 3. **Human‑in‑the‑loop:** After automation finishes, an admin manually verifies everything before the old version is finally removed. The root cause was that Celery workers, upon initialization, immediately received and executed a burst of tasks, spiking CPU usage. Lowering Celery’s concurrency would have helped, but it would also slow asynchronous processing during the rollout—something I didn’t want. The idea that clicked was: pause the existing Celery workers just long enough to free up CPU, deploy the new code, then resume them, achieving zero‑downtime without overloading the machine. --- ## 3. Core Code Walkthrough {#sec-089c44586f5b} You can find the full script in my [GitHub repository](https://github.com/mikihands/linuxscript/tree/main/zero-downtime). Below are a few key snippets. ### ① Isolating Projects with Docker Compose {#sec-bbea3915a962} Using the `docker compose -p` flag, I create two separate projects—`blue` and `green`—from the same compose file. ```bash dc() { # Dynamically set the project name (-p) for isolated environments docker compose -f "$COMPOSE_FILE" "$@" } ``` ### ② Rigorous Health Checks {#sec-d614d4176094} Traffic is never switched until the new version passes a health check. ```bash health_check() { # Retry up to 10 times, ensuring the target port returns 200 OK if curl -fsSIL --max-time "$HEALTH_TIMEOUT" "$url"; then ok "Health check passed" return 0 fi } ``` ### ③ Graceful Rollback on Failure {#sec-eafcad807577} If the new version misbehaves, the script quickly brings the old services back online, avoiding any outage. Instead of force‑killing Celery workers and beat, I use a lightweight `stop` to reclaim CPU while keeping the processes ready for an instant restart. --- ## 4. Operational Tip: The Art of “Verify‑Then‑Delete” {#sec-1ff4e831798d} The script ends by prompting the admin to manually confirm the deployment before cleaning up the old version. > "Deployment succeeded. Please log in and verify everything. If all looks good, copy the command below to clean up the previous version." That single safeguard catches the 1 % of errors automation might miss. --- ## 5. Closing Thoughts {#sec-299720b6e769} This script embodies the compromises required to squeeze maximum efficiency out of limited resources. While it’s a modest piece of code, it’s been a reliable workhorse for me, and I hope it helps other small‑scale developers facing similar constraints. **Related Links:** * [Direct link to the GitHub repository](https://github.com/mikihands/linuxscript/tree/main/zero-downtime) * [My custom automated deployment system using GitHub Webhooks – Part 5: Nginx, HTTPS, and final integration](/ko/whitedec/2025/7/24/github-webhook-final-nginx-https/) * Feel free to leave comments or open an Issue on GitHub for any questions!