Zero-Downtime Deployments for Solo Developers
You don't need a platform team to deploy without downtime. Here's a straightforward blue-green strategy using Nginx, rsync, and a simple shell script.
Deployments shouldn’t mean “site goes down for 30 seconds while I swap files.” Even if you’re a solo developer running a VPS, zero-downtime deploys are achievable with basic tools you probably already have.
The concept: blue-green deployment
The idea is simple: maintain two identical directories (blue and green). One is live, the other is idle. You deploy to the idle one, test it, then switch traffic over instantly.
/var/www/
blue/ # currently live
green/ # deploy here next
current # symlink to blue/
Nginx points at /var/www/current, which is a symlink. Switching means updating the symlink, an atomic operation.
Step 1: Directory structure
sudo mkdir -p /var/www/{blue,green}
sudo ln -sfn /var/www/blue /var/www/current
Step 2: Nginx config
server {
listen 80;
server_name yourdomain.com;
root /var/www/current;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
Nginx follows the symlink, so when we update it, new requests hit the new directory. Existing connections finish on the old one.
Step 3: Deploy script
Here’s a minimal deploy script:
#!/bin/bash
set -e
LIVE=$(readlink /var/www/current)
if [ "$LIVE" = "/var/www/blue" ]; then
TARGET="/var/www/green"
else
TARGET="/var/www/blue"
fi
echo "Deploying to $TARGET..."
rsync -az --delete ./dist/ "$TARGET/"
echo "Switching symlink..."
ln -sfn "$TARGET" /var/www/current
echo "Live: $(readlink /var/www/current)"
echo "Done. Zero downtime."
Step 4: Rollback
Rolling back is just switching the symlink back:
ln -sfn /var/www/blue /var/www/current
# or
ln -sfn /var/www/green /var/www/current
Takes less than a second. The old version is still sitting there, untouched.
When to use this
This works great for:
- Static sites (Astro, Hugo, Next.js static export)
- Simple PHP apps
- Any situation where the “build” produces a directory of files
For apps with databases, you’ll need to handle migrations separately. The deploy strategy stays the same, but you’ll want to ensure migrations are backward-compatible.
Going further
- Add a
health_checkstep before switching the symlink - Integrate with GitHub Actions: push to
main-> SSH -> run deploy script - Keep the last 3-5 deploys for easy rollback with timestamped directories
You don’t need Kubernetes to deploy like a professional. A symlink, rsync, and 10 lines of bash go a long way.
Need help applying this?
Turn this guide into a working setup
Start with a free diagnostic or request a paid audit. We can help you move from article-level advice to a stable implementation plan.