## 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.

```bash
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`:

```yaml
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.

```bash
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](/docs/deployment/edge-and-dns-setup).
