> ## Documentation Index
> Fetch the complete documentation index at: https://docs.reachcrew.space/llms.txt
> Use this file to discover all available pages before exploring further.

# Your own domain

> Run ReachCrew on a subdomain such as app.example.com over HTTPS: DNS, Caddy with Docker Compose or Dokploy, Cloudflare, and what to update after a move.

ReachCrew is meant to live on a subdomain of your company's domain, for example `app.example.com`, while your website stays on `example.com`. The hosted ReachCrew runs this way at `app.reachcrew.ai`. One image serves any domain: the address is a runtime setting, so nothing is rebuilt.

> [!NOTE]
>
> **What you need**
>
> * A working install ([Docker Compose](https://docs.reachcrew.space/self-hosting/docker-compose.md) or [Dokploy](https://docs.reachcrew.space/self-hosting/dokploy.md)).
> * A domain whose DNS you can edit.
> * A server with ports 80 and 443 open to the internet.

## 1. DNS

Add an `A` record for the subdomain pointing at your server's IPv4 address (and an `AAAA` record for IPv6, if it has one):

| Type | Name | Value |
| - | - | - |
| `A` | `app` | `203.0.113.10` (your server) |

Check it before going on: `dig +short app.example.com` must print your server's address. The certificate cannot be issued until it does.

## 2a. Docker Compose: Caddy

`docker-compose.https.yml` adds [Caddy](https://caddyserver.com), which gets and renews a Let's Encrypt certificate on its own. Download it next to `docker-compose.yml`:

```sh theme={null}
curl -O https://raw.githubusercontent.com/rishav887/reachcrew/main/docker-compose.https.yml
```

Add to `.env`:

```sh theme={null}
COMPOSE_FILE=docker-compose.yml:docker-compose.https.yml
APP_DOMAIN=app.example.com
```

With your own PostgreSQL as well, list all three files: `COMPOSE_FILE=docker-compose.yml:docker-compose.external-db.yml:docker-compose.https.yml`.

Then `docker compose up -d` and open `https://app.example.com`. The first request takes a few seconds while the certificate is issued; `docker compose logs caddy` shows it.

What changes:

* `APP_URL` becomes `https://<APP_DOMAIN>`. Do not set `APP_URL` yourself as well.
* The app's port 3000 is no longer published. Everything goes through Caddy, which is also what makes the client address that rate limits use trustworthy.
* Uploads up to 50 MB (lead imports) and requests up to 10 minutes (imports, exports) pass through.

Because `APP_URL` is no longer `localhost`, the app refuses to start while any `CHANGEME` secret remains. Replace them first (`openssl rand -hex 32`).

## 2b. Dokploy

Dokploy's router already terminates HTTPS. In the application's **Domains** tab, add `app.example.com`, port `3000`, HTTPS on, certificate **Let's Encrypt**. Then set `APP_URL=https://app.example.com` (or `BETTER_AUTH_URL`) under **Environment** and redeploy. See [Dokploy](https://docs.reachcrew.space/self-hosting/dokploy.md).

## Behind Cloudflare

With the record proxied (orange cloud):

* Set SSL/TLS mode to **Full (strict)**. Caddy and Dokploy hold real certificates, so strict works, and Flexible would loop redirects.
* Set `CLIENT_IP_HEADER=cf-connecting-ip`. Otherwise every request seems to come from a Cloudflare address, and sign-in and request rate limits would count all your users as one.
* Only do this while the server is reachable through Cloudflare alone (firewall ports 80 and 443 to [Cloudflare's ranges](https://www.cloudflare.com/ips/)): anyone reaching it directly could set that header.

## 3. After the address changes

The address is stored in a few places outside ReachCrew. After moving (from `localhost`, or from another domain):

1. **Unipile:** Settings → LinkedIn → Connection → **Register again**. Webhook URLs carry the old address until you do, and registration is skipped entirely on `localhost`.
2. **Google sign-in** (if used): add `https://app.example.com/api/auth/callback/google` to the OAuth client's redirect URIs.
3. **Call recorder extension:** it trusts `https://app.reachcrew.ai` out of the box. For your own domain, each caller adds it once on the extension's Options page ([details](https://docs.reachcrew.space/self-hosting/production.md#whatsapp-call-recorder-extension)).
4. **People's sessions:** sign-in cookies belong to the old address, so everyone signs in again once.

## Troubleshooting

> [accordion] The browser shows a certificate error, or Caddy logs 'challenge failed'
>
> Let's Encrypt could not reach the server on port 80 for this name. Check that the DNS record resolves to this server, that ports 80 and 443 are open in the firewall and the cloud provider's security group, and that nothing else (an old nginx) holds port 80. Behind Cloudflare, set SSL to Full (strict). Then `docker compose restart caddy`.

> [accordion] Too many redirects
>
> Cloudflare's SSL mode is Flexible: it calls the server over http, which redirects to https, forever. Set it to Full (strict).

> [accordion] Sign-in or email links still point at localhost
>
> `APP_URL` (or `BETTER_AUTH_URL`) still holds the old address. With the Caddy file it comes from `APP_DOMAIN`; remove any `APP_URL` line from `.env` and run `docker compose up -d` again.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.