# Domains

> Give a Falak site a generated sslip.io domain, a test domain or your own custom domain — with the DNS records to add, a live DNS check and www redirects.

Source: https://falak.sh/docs/guides/domains/

Every public endpoint of a site needs a domain. Falak offers three kinds, all with automatic HTTPS:

| Kind | Example | DNS setup | Best for |
|---|---|---|---|
| **Generated** | `shop.203-0-113-20.sslip.io` | none | Trying things out, internal tools |
| **Test domain** | `shop.test.acme.dev` | one wildcard record, once | Staging and previews on your own domain |
| **Custom** | `shop.example.com` | an A/AAAA record per site | Production |

## Generated domains

A generated domain is `<label>.<ipv4-with-dashes>.<suffix>`, for example `minio-files.63-182-218-247.sslip.io`. Wildcard DNS services like [sslip.io](https://sslip.io) resolve any such name to the IP inside it, so it works immediately, and Let's Encrypt issues a certificate over HTTP-01.

| Rule | Detail |
|---|---|
| Label | The site slug. Compose services: `<service>-<slug>`. |
| IP | The leader server's public IPv4, or the load balancer's |
| Suffix | `sslip.io` by default; `nip.io`, a self-hosted sslip.io server, or off |
| Default | Used when no test domain is configured |

Choose the provider for your organization in **Settings → Domains** (sslip.io, nip.io, off, or the server default). Operators set the server default with `FALAK_GENERATED_DOMAIN_SUFFIX` (`sslip.io`, `nip.io`, your own sslip.io-style domain, or `off`).

sslip.io and nip.io names are shared by all their users: they share Let's Encrypt rate limits and have no cookie isolation between sites. Use your own domain in production.

A generated domain needs a server with a public IPv4. On several servers without a load balancer, it reaches the leader only.

## Test domain

Operators can configure a wildcard **test domain**. Every site then gets `<slug>.` (Compose: `<service>-<slug>.…` after the first service), and it becomes the default choice for new services.

1. Create a wildcard DNS record `*.test.acme.dev` pointing at your server (or load balancer).
2. Set `FALAK_TEST_DOMAIN=test.acme.dev` in `/opt/falak/.env` and run `falak-ctl up`.
3. Optional: `FALAK_TEST_DOMAIN_TLS=internal` for private setups (default `acme`, Let's Encrypt per name).

Turn a site's test domain on or off under **Settings → Networking**.

## Custom domains

1. Open the site's **Settings → Networking** and click **Add domain** (or choose **Custom** when you create the service).
2. Enter the name, for example `shop.example.com`.
3. Falak shows the DNS records to add and checks DNS live until the name points at the right place:

   | Target | Record |
   |---|---|
   | Site behind a load balancer | `A` → the load balancer's IPv4 (and `AAAA` → its IPv6) |
   | Site on one server | `A` → the server's IPv4, `AAAA` → its IPv6 |
   | Site on several servers, no load balancer | One `A`/`AAAA` per server (DNS round-robin) |

   For a subdomain of a single-server site, Falak also offers a `CNAME` to the site's generated name as an alternative.

4. Once DNS matches, the certificate is issued automatically and the status turns green.

### DNS check statuses

| Status | Meaning |
|---|---|
| `ok` | Every address the name resolves to is one of the targets |
| `mismatch` | It resolves elsewhere ("Resolves to 1.2.3.4 — expected …"), or has extra records to remove |
| `proxied` | Cloudflare proxy addresses: set the record to **DNS only** until the certificate is issued |
| `missing` | No A/AAAA record yet |
| `error` | Lookup failed, invalid name, or no server IP to compare with |

The check resolves names from the control plane over DNS-over-HTTPS (`FALAK_DNS_RESOLVER=doh`, `FALAK_DNS_DOH_URL` default `https://cloudflare-dns.com/dns-query`), so a new record shows up as soon as it is published, without waiting for local caches. Set `FALAK_DNS_RESOLVER=system` to use the host's resolver. You can also run the check through the [DNS API](/docs/api/domains-and-dns/).

## Primary domain and www

- The **primary** domain is the canonical host. Make another domain primary from its row menu. `APP_URL` for new Laravel sites uses the domain chosen at creation.
- **www redirect** per domain: none, to `www`, or to the apex (`none`, `to_www`, `to_apex`).
- A domain name can belong to only one site.
- Every public service of a Compose site has its own domains, with their own primary and www settings: pick the service in **Settings → Networking**. See [Compose apps from git](/docs/guides/compose-apps/#edge-for-every-public-service).

## Cloudflare

- **Connect Cloudflare** and Falak creates and removes the records itself, generates names under your zone and works behind the orange cloud. See [Cloudflare](/docs/guides/cloudflare/).
- Without the integration, keep records **DNS only** (grey cloud) while the certificate is issued; Falak detects proxied records.
- For wildcard certificates or hosts Let's Encrypt cannot reach, use **DNS-01** with a Cloudflare API token. See [TLS certificates](/docs/guides/tls-certificates/).

## Limits

- One generated name per endpoint. A site on several servers without a load balancer is reached on the leader only.
- Generated domains need a public IPv4; `422` otherwise.

## Next steps
