Today we migrated to a new Hetzner server, registered fxledger.de, and went live with HTTPS. It should have taken an hour. It took most of the morning — but it was worth it.
The migration
Moving from the old server to the new one was mostly smooth. PostgreSQL dump, Docker volume backup for uploads, copy the .env file, restore on the new machine. The only surprise: the uploads directory didn't exist on the host — it was inside a Docker named volume at /var/lib/docker/volumes/.... You can't just tar the directory, you have to go through Docker's volume path.
Let's Encrypt and the IPv6 problem
Certbot kept failing with a 404 on the ACME challenge. Baffling, because our test file was accessible from our own machine. The error always came from the same IPv6 address: 2a01:4f8:d0a:27bd::2.
Solution: delete the AAAA record entirely. The new server runs IPv4-only and that's fine. After that, Certbot issued the certificate in seconds. Lesson: always check that your DNS records actually point where you think they do before debugging nginx.
There was also a secondary issue: nginx's default site was catching requests before our fxledger.de server block got a chance. Removing it from sites-enabled fixed that. Now the redirect chain is exactly what it should be: HTTP → HTTPS, www → apex domain, and the app loads cleanly.