While making sure this very site (giovanni.pw) had a real domain and real SSL configured on Canopy Host, not just the platform’s auto-generated internal address, I removed the leftover internal .apps.canopy.pm domain that Dokku generates by default. Routine cleanup. Except https://giovanni.pw/ immediately stopped serving: TLS handshake, unrecognized name.
The cause was a real bug, not a fluke: dokku letsencrypt:disable/:enable operate per-app, not per-domain. One certificate covers every vhost on the app. The domain-removal route called ssl().disable() unconditionally, before removing any domain, on the assumption that disabling was scoped to the one domain being deleted. It wasn’t. Removing the harmless internal domain nuked HTTPS for the real one sitting right next to it.
The recovery was immediate. Re-running the SSL-enable step restored the cert in seconds. But the more useful part was what came after: fixing the actual bug rather than just moving on once the site was back up. The route now checks whether any other domain still needs SSL before touching the app-wide setting at all; it only tears down certificates entirely when the domain being removed is the last one left. Two tests now cover exactly this: remove-with-a-sibling-domain-remaining, and remove-as-the-last-domain, so the distinction can’t quietly regress again.
Nothing about this was exotic. It was a five-minute mistake, caught by immediately checking the live site instead of assuming the change had worked, then turned into a permanent fix with real test coverage instead of a one-off manual patch.