Zero-Downtime Nginx to Caddy Migration: A Homelab Step-by-Step Guide

Migrating your homelab reverse proxy from Nginx to Caddy is way easier than it sounds—especially when you do it without downtime. Below is a straight-to-the-point guide you can copy-paste into WordPress. No Markdown, just clear steps and bullet points.

What you’ll get out of this post
– Full backup of every Nginx config and TLS cert
– One-line conversion of your Nginx config to Caddyfile syntax
– Automatic HTTPS with zero manual work
– Reload strategy that keeps every site online

1. Snapshot the current Nginx setup
• Make a directory: mkdir ~/nginx-backup/$(date +%F)
• Copy all config files: sudo cp -r /etc/nginx ~/nginx-backup/$(date +%F)/
• Copy live certificates: sudo cp -r /etc/letsencrypt ~/nginx-backup/$(date +%F)/
• Zip it: tar -czf nginx-full-backup-$(date +%F).tar.gz ~/nginx-backup/$(date +%F)

2. Install Caddy next to Nginx
• Debian/Ubuntu: sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/deb.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update && sudo apt install caddy
• Verify: caddy version

3. Convert Nginx configs to Caddyfile automatically
• Grab the open-source converter: go install github.com/caddyserver/nginx-adapter/cmd/nginx-adapter@latest
• Convert everything in one shot: nginx-adapter /etc/nginx/sites-enabled/* > Caddyfile
• Review warnings: nginx-adapter -v /etc/nginx/sites-enabled/*

4. Test the new Caddyfile before going live
• Dry-run: caddy validate --config Caddyfile
• If you see green, you’re good.
• Fix any red lines—usually just rewrite or header tweaks.

5. Start Caddy without killing Nginx
• Bind to port 81 temporarily so both servers run side-by-side: edit Caddyfile and change the default bind address to :81
• Start Caddy: sudo systemctl start caddy

6. Switch ports and reload without downtime
• Edit Caddyfile again, reset port to 80 and 443
• Reload Caddy (graceful): sudo systemctl reload caddy
• Stop Nginx only after Caddy is confirmed listening: sudo systemctl stop nginx && sudo systemctl disable nginx

7. Verify HTTPS and automatic renewals
• Check TLS status: caddy adapt --config Caddyfile | jq '.apps.tls'
• Watch logs: sudo journalctl -u caddy -f

Quick rollback path
• If anything breaks, restart Nginx: sudo systemctl start nginx
• Point traffic back by swapping ports or DNS.

Wrap-up & next steps
Test all sub-domains, cron your backups weekly, and celebrate one less headache in your homelab. Got questions? Drop them in the comments and I’ll answer each one within 24 hours—pinkie promise.

Related: VR Homelab Setup Guide: From Zero to Ready in 3 Simple Steps.

Related: How to Install OpenClaw on Ubuntu Server: A Step-by-Step Guide.


Discover more from Susiloharjo

Subscribe to get the latest posts sent to your email.

Discover more from Susiloharjo

Subscribe now to keep reading and get access to the full archive.

Continue reading