How do I point a domain at a server running Kamal?
Create an A record for the apex pointing at the server's public IPv4 address, and a CNAME for www pointing at the apex. Set the same hostname in the proxy section of config/deploy.yml and redeploy. Kamal's proxy requests a certificate on the first request to that host, so HTTPS starts working within a minute of DNS resolving.
The records
| Type | Name | Value |
|---|---|---|
| A | @ |
your server's IPv4 address |
| CNAME | www |
yourdomain.com |
Keep the TTL low, around 300 seconds, until you are confident. You can raise it later, and a low TTL means a mistake costs five minutes rather than a day.
dig +short yourdomain.com
curl -sI https://yourdomain.com/up | head -1
Tell Kamal which host it is serving
The proxy needs the hostname to request a certificate for it. That lives in config/deploy.yml:
proxy:
ssl: true
host: yourdomain.com
Redeploy after changing it. The certificate is requested on the first request that arrives for that host, so the sequence is: DNS resolves, a request lands, the certificate is issued, and the second request is already on HTTPS.
Also set APP_HOST
This one is silent when you miss it. Rails builds absolute URLs for emails, canonical tags and the
sitemap from APP_HOST, not from the request. Without it, a magic-code email links to
localhost:3000 and the link does not work for anyone.
bin/kamal app exec 'bin/rails runner "puts Rails.application.config.x.app_host"'
The two things that make this look broken when it is not
DNS caching. Your machine may hold the old answer for as long as the previous TTL. dig against
a public resolver directly, such as dig @1.1.1.1 yourdomain.com, tells you what the world sees
rather than what your laptop remembers.
A proxy in front. If you put Cloudflare or another CDN ahead of the server, it terminates TLS itself and Kamal's certificate request may never see a request. That setup needs its own configuration, covered in Edge and DNS Setup.