diff --git a/docs/concepts/domains.mdx b/docs/concepts/domains.mdx
index 110bbc0d94..79a31eb96d 100644
--- a/docs/concepts/domains.mdx
+++ b/docs/concepts/domains.mdx
@@ -15,22 +15,35 @@ To make your service accessible from the public internet with Defang-hosted doma
### Structure
-Defang-hosted domains use a structure that is based on your username and service name.
+When you deploy a publicly accessible service, Defang automatically provides you with domain names to access it.
-If you have a publicly accessible service, you will automatically receive a domain to access it. If you're deploying to the [Defang Playground](./defang-playground.md), your domain will be structured as follows:
+If you're deploying to the [Defang Playground](./defang-playground.md), you will receive:
+**Defang-hosted domain:**
```
https://---.defang.dev
```
-If you're using [Defang BYOC](./defang-byoc.md), your domain will be:
+If you're using [Defang BYOC](./defang-byoc.md), you will receive **both**:
+**Defang-hosted domain:**
```
https://--...defang.app
```
+
+**Cloud provider load balancer domain** (AWS example):
+```
+https://defang-xyz-b0f79bb-123456789012.ca-central-1.elb.amazonaws.com
+```
+
+:::tip Choosing Between Domains
+- Use the **Defang-hosted domain** (`defang.app`) for convenience and simplicity
+- Use the **cloud provider domain** (e.g., AWS ELB) if you want to avoid dependency on Defang infrastructure
+- Both domains point to the same service and work identically
+:::
@@ -72,18 +85,44 @@ const service = new defang.DefangService("serviceName", {
You can also bring your own domain to a Defang project. This allows you to use your own domain name to access your services, and varies a little bit depending on your setup.
-### BYOC or Defang Playground
+## DNS Management Options
+
+When bringing your own domain, you have two main approaches:
+
+### Option 1: Using Your Existing DNS Provider (CloudFlare, Namecheap, etc.)
-If you are using [Defang BYOC](./defang-byoc.md) and *do not* have your domain's DNS hosted with your cloud provider, or if you are using the [Defang Playground](./defang-playground.md), you will need to follow this flow:
+If you are using [Defang BYOC](./defang-byoc.md) and *do not* have your domain's DNS hosted with your cloud provider, or if you are using the [Defang Playground](./defang-playground.md), you have two choices:
+**A. Point directly to your custom domain:**
1. Add the `domainname` to your service definition.
2. Run `defang compose up` to deploy your project.
3. Run `defang cert generate` to generate an SSL certificate. This command will provide instructions for where to point your domain's DNS before the certificate can be issued.
+4. **Note:** You will need to run `defang cert generate` again after each `defang compose up` to recreate SSL certificates.
-### BYOC
+**B. Use CNAME to Defang-hosted domain (Recommended for frequent deployments):**
+
+If you frequently deploy and tear down your services (e.g., for staging environments), you can avoid reconfiguring DNS each time by using a CNAME record:
+
+1. Don't add a `domainname` to your service definition.
+2. Run `defang compose up` to deploy your project.
+3. Defang will provide you with a `defang.app` domain (e.g., `service-name--port.project-name.username.defang.app`) and an AWS load balancer domain (e.g., `defang-xyz-b0f79bb-123456789012.ca-central-1.elb.amazonaws.com`).
+4. In your DNS provider, create a CNAME record pointing your custom domain to the `defang.app` domain or the AWS load balancer domain.
+5. You'll still need to run `defang cert generate` once to create the SSL certificate, but you won't need to update your DNS records on subsequent deployments.
+
+:::tip Managing Multiple Environments
+Use the `--project-name` flag or the `name:` field in your Compose file to create separate environments. For example, a project named "hello" with `--project-name hello-staging` would create a separate deployment, allowing you to maintain both production and staging environments simultaneously.
+:::
+
+### Option 2: Using Route 53 (AWS) - Automatic DNS Management
If you are using [Defang BYOC](./defang-byoc.md) *and the DNS for your domain is hosted with your cloud provider* (i.e. a Hosted Zone in Route 53, if you're using AWS), all you need to do is specify the `domainname` in your service definition, as in the example below.
+**Benefits of Route 53:**
+- DNS records are automatically created and updated
+- SSL certificates are automatically provisioned and renewed
+- No need to run `defang cert generate` after each deployment
+- Ideal for environments that are frequently deployed and torn down
+
:::warning
For the time being, you can only use one domain per service.
If you need to use multiple domains, please vote on this [issue](https://github.com/DefangLabs/defang/issues/247).
diff --git a/docs/tutorials/use-your-own-domain-name.mdx b/docs/tutorials/use-your-own-domain-name.mdx
index 45daecf9ea..9ff6850857 100644
--- a/docs/tutorials/use-your-own-domain-name.mdx
+++ b/docs/tutorials/use-your-own-domain-name.mdx
@@ -6,6 +6,10 @@ title: How to Use Your Own Domain
This tutorial will show you how to set up and use your own domain when deploying to AWS using Defang.
+There are two main approaches to using custom domains with Defang on AWS:
+1. **Using Route 53 for DNS management** (Recommended) - Automatic DNS and certificate management
+2. **Using your existing DNS provider** - Manual DNS configuration with CNAMEs
+
## Prerequisites
@@ -14,6 +18,16 @@ This tutorial will show you how to set up and use your own domain when deploying
* [The Defang CLI](/docs/intro/getting-started#install-the-defang-cli)
* [AWS Account Credentials](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-authentication.html)
+## Approach 1: Using Route 53 (Recommended)
+
+This approach is ideal if you want automatic DNS and certificate management, especially for frequently deployed environments like staging.
+
+**Benefits:**
+- No need to run `defang cert generate` after each deployment
+- DNS records are automatically created and updated
+- SSL certificates are automatically provisioned and renewed
+- Perfect for staging environments that are frequently deployed and torn down
+
## Step 1 - Set up a Hosted Zone in AWS Route 53
:::info
@@ -46,8 +60,9 @@ services:
context: ./web
dockerfile: Dockerfile
ports:
- target: 3000
- mode: ingress
+ - mode: ingress
+ target: 3000
+ protocol: http
```
@@ -63,4 +78,102 @@ This will deploy your service and set up the necessary DNS records in Route 53 a
***
+## Approach 2: Using Your Existing DNS Provider (CloudFlare, Namecheap, etc.)
+
+If you prefer to keep your DNS with your current provider (like CloudFlare or Namecheap), you can use CNAME records to point to Defang-provided domains. This approach is particularly useful for frequently deployed environments.
+
+### Option A: Direct Custom Domain with Certificate Generation
+
+1. Add the `domainname` to your service definition in your Compose file:
+ ```yaml
+ services:
+ web:
+ domainname: staging.example.com
+ ports:
+ - mode: ingress
+ target: 3000
+ protocol: http
+ ```
+
+2. Deploy your service:
+ ```bash
+ defang compose up
+ ```
+
+3. Generate an SSL certificate:
+ ```bash
+ defang cert generate
+ ```
+ This command will provide instructions for DNS configuration.
+
+4. **Important:** You'll need to run `defang cert generate` again after each `defang compose up` to recreate SSL certificates.
+
+### Option B: CNAME to Defang Domain (Recommended for Staging)
+
+This approach avoids having to reconfigure DNS and regenerate certificates for each deployment, making it ideal for staging environments that are frequently torn down and redeployed.
+
+1. **Don't** add a `domainname` to your service definition. Just expose the port:
+ ```yaml
+ services:
+ web:
+ ports:
+ - mode: ingress
+ target: 3000
+ protocol: http
+ ```
+
+2. Deploy your service:
+ ```bash
+ defang compose up
+ ```
+
+3. After deployment, Defang provides you with two domains:
+ - **Defang-hosted domain**: `service-name--port.project-name.username.defang.app`
+ - **AWS load balancer domain**: `defang-xyz-b0f79bb-123456789012.ca-central-1.elb.amazonaws.com`
+
+4. In your DNS provider (CloudFlare, Namecheap, etc.), create a CNAME record:
+ - **Name**: `staging` (or your desired subdomain)
+ - **Target**: Either the `defang.app` domain or the AWS ELB domain
+ - **Example**: `staging.example.com` → `web--3000.myproject.myuser.defang.app`
+
+5. Run `defang cert generate` once to create the SSL certificate for your CNAME.
+
+6. For subsequent deployments, simply run `defang compose up`. Your CNAME record will continue to work without needing DNS changes.
+
+### Managing Multiple Environments
+
+To maintain separate staging and production environments simultaneously, use project names:
+
+**Using the `name` field in your Compose file:**
+```yaml
+name: myapp-staging
+
+services:
+ web:
+ ports:
+ - mode: ingress
+ target: 3000
+ protocol: http
+```
+
+**Or using the `--project-name` flag:**
+```bash
+defang compose up --project-name myapp-staging
+defang compose up --project-name myapp-production
+```
+
+Each project name creates a separate deployment with its own domain:
+- Staging: `web--3000.myapp-staging.username.defang.app`
+- Production: `web--3000.myapp-production.username.defang.app`
+
+:::tip
+Create CNAMEs for both environments:
+- `staging.example.com` → `web--3000.myapp-staging.username.defang.app`
+- `app.example.com` → `web--3000.myapp-production.username.defang.app`
+
+Then you can deploy and tear down your staging environment as needed without touching DNS.
+:::
+
+***
+
For a deeper discussion of how to use a custom domain with Defang, see our [Domain](/docs/concepts/domains) concept docs.