TLS / Let’s Encrypt
If the previous pages are done — DNS points at the VPS, firewall allows 80+443, Caddy is running with the Hiveloom Caddyfile — the first request to your hostname triggers ACME issuance automatically.
Trigger issuance
curl -I https://hiveloom.example.com/Expect a first request to stall for 5–30 seconds while Caddy negotiates the certificate. Subsequent requests are instant.
Verify
curl -s https://hiveloom.example.com/healthz
# {"status":"ok"}
curl -s https://hiveloom.example.com/.well-known/oauth-authorization-server | jqThe OAuth metadata URLs must start with https://. If they start with
http://, the proxy isn’t forwarding X-Forwarded-Proto: https. Revisit
Reverse proxy.
Iterate without triggering rate limits
Let’s Encrypt rate-limits heavily on repeat attempts for the same hostname. When iterating, use staging:
hiveloom tls render --host hiveloom.example.com --email [email protected] --acme-env stagingThe resulting cert is not publicly trusted; add -k to curl. Swap back to
production with a fresh render + reload once things look right.
Port scan
From another host:
nmap -Pn -p 1-10000 hiveloom.example.comOnly SSH, 80, and 443 should answer. If port 3000 (or any other upstream) answers, something is wrong — see Firewall and systemd.
Common ACME failures
context deadline exceeded — two causes:
- DNS doesn’t resolve to this VPS from Let’s Encrypt’s vantage.
- TCP/80 is blocked upstream (cloud security group, not UFW).
Port 80 must be reachable from the internet, not just from the VPS itself. Check your cloud provider’s security group as well as UFW.
rate limit exceeded — you’ve tried too many times. Wait an hour and use
--acme-env staging until you have a clean run, then switch back.
Certificate issued but OAuth metadata still says http:// — the proxy isn’t
forwarding X-Forwarded-Proto: https. Re-check
Reverse proxy.
Next: systemd.