The dream is a single command that rebuilds your whole VPS from scratch: Ansible provisions the box, Compose brings up the apps, Traefik gets certs, mail flows, done. The reality is that even when it works, it feels fragile — you're never quite sure it'll come back identical, so you avoid testing it, which makes it more fragile. The fragility isn't random. It clusters in three places: TLS/edge, mail, and state. Harden those and a from-scratch rebuild becomes something you trust enough to actually run.
Why "automated" still feels risky
Provisioning packages and writing config files is the easy, idempotent 80%. The scary 20% is everything with an external dependency or persistent state: certificates issued by a rate-limited CA, mail that depends on DNS and reputation, and data that must survive the rebuild. Those don't reset cleanly, so a naive rebuild can hit a Let's Encrypt rate limit, send mail that bounces, or come up with empty databases.
Fragile part 1: Traefik and TLS
Certificate issuance is the classic rebuild trap. Rebuild too often and Let's Encrypt rate-limits you; lose the acme.json and every cert reissues at once.
- Persist
acme.jsonon a volume that survives rebuilds, so certs are reused, not reissued. - Use the DNS-01 challenge for wildcard/many-subdomain setups so issuance doesn't depend on the box being publicly reachable mid-rebuild.
- Make sure renewal reloads cleanly — the exact failure in Let's Encrypt renew-and-reload behind a proxy.
Fragile part 2: mail
Mail is fragile because deliverability lives in DNS and reputation, not in your playbook. A rebuilt server with default mail config sends mail that lands in spam or is rejected outright.
- Keep SPF, DKIM, and DMARC as code/DNS that the rebuild references — see the mail-server domain prerequisites.
- Persist DKIM keys across rebuilds (rotating them on every rebuild breaks alignment).
- After a rebuild, send a test message and check it lands before trusting password resets and alerts to it.
Fragile part 3: state
Automation that rebuilds the machine but forgets the data is worse than no automation — it confidently produces an empty box. Separate cleanly:
- Code/config → in the repo, fully reproducible.
- Data → in volumes/backups, restored as a deliberate step, never assumed.
The rebuild playbook should restore state, and you should have drilled that restore. This is the same code-vs-state line that makes OS-EOL rebuilds safe.
Make it trustworthy by testing it
The reason rebuild automation feels fragile is that it's rarely exercised. Fix that:
- Rebuild onto a throwaway VPS regularly and verify every app comes up with its data.
- Keep the playbook idempotent — running it twice changes nothing the second time.
- Pin versions so "rebuild" doesn't silently mean "upgrade everything" and inherit Compose drift.
Checklist
-
acme.jsonpersisted; DNS-01 for wildcards; renewal reloads. - SPF/DKIM/DMARC as code; DKIM keys persisted; post-rebuild mail test.
- Code in repo, data in backups; restore is an explicit, drilled step.
- Playbook idempotent and version-pinned.
- Rebuild rehearsed on a throwaway box, end to end.
Takeaway
Rebuild automation feels fragile because the stateful, externally-dependent parts — TLS, mail, data — don't reset cleanly. Persist certs and DKIM keys, treat data restore as an explicit step, pin versions, and rehearse the whole thing on a throwaway box. Do that and "rebuild the VPS" becomes a command you trust instead of one you're afraid to run.
From across the StoicSoft network
Hand-curated reads on the same topic from sister sites in the StoicSoft family.

