Skip to main content
Caddy is the shortest path from “she runs on port 4007” to “she is live at https://postqueen.example.com”. It gets your certificate from Let’s Encrypt on its own and renews it without being asked, so there is nothing to schedule and nothing to remember. If you are not sure what a reverse proxy is or why you need one, Domain and HTTPS explains it first.

Before you start

Two things have to be true:
  • Your domain’s A record points at this server. Check with dig +short postqueen.example.com.
  • Ports 80 and 443 are open. Caddy needs 80 to prove it owns the domain, even though your visitors only ever use 443.

Set it up

1

Install Caddy

On Ubuntu or Debian:
Other systems are covered on Caddy’s install page.
2

Write the configuration

Replace everything in the file with this, using your own domain:
That is the whole configuration. Caddy sees a real domain name, so it requests a certificate automatically the first time someone visits.
Why 4007? Inside the container she listens on port 5000, and the Compose file publishes that as 4007 on the host. If you installed her with Docker on its own rather than Compose, she is on localhost:5000 and that is the number to use here instead.
Save with Ctrl+O, Enter, then Ctrl+X.
3

Reload Caddy

Watch it get the certificate:
A line containing certificate obtained successfully means you are done. Press Ctrl+C to stop watching.
4

Tell PostQueen her address

The proxy now works, but she still thinks she lives on localhost. In your docker-compose.yaml:
Keep the /api on the last one, and leave no trailing slashes. Then apply it:
5

Check it

From your own machine:
HTTP/2 200 means the certificate, the proxy and PostQueen are all working. Open the address in a browser and sign in.

Testing on a private network

If the name is not reachable from the public internet, for example on a home network, Caddy cannot use Let’s Encrypt. It can issue its own certificate instead:
Browsers will not trust that certificate until you install Caddy’s local authority on each machine, which Caddy’s documentation covers. For anything public, leave tls internal out and let it use Let’s Encrypt.

If it does not work

Almost always DNS or a blocked port. dig +short postqueen.example.com has to return this server’s IP, and port 80 has to be reachable from the internet. sudo journalctl -u caddy -n 50 usually names the reason outright.
Caddy is fine, PostQueen is not answering. Check her directly on the server with curl -I http://localhost:4007. If that fails too, docker compose logs postqueen is where to look.
FRONTEND_URL does not match the address in the browser bar. It has to be identical, including https:// and without a trailing slash, because her allowed-origin list is built from it.
Caddy does not limit request size by default, so this is usually PostQueen’s own 50 MB limit on posts. Uploads and Storage covers uploading larger media properly.