From a9a97c8f7da9317fa10f832c2f0d255a1f382d91 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 10 Dec 2025 01:20:18 +0000 Subject: [PATCH 1/5] Initial plan From 794814d251e28d133c51ef61cd37b21ea480f451 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 10 Dec 2025 01:27:10 +0000 Subject: [PATCH 2/5] Update BYOD docs with DNS management options and staging workflow Co-authored-by: lionello <591860+lionello@users.noreply.github.com> --- docs/concepts/domains.mdx | 51 +++++++-- docs/tutorials/use-your-own-domain-name.mdx | 109 ++++++++++++++++++++ 2 files changed, 154 insertions(+), 6 deletions(-) diff --git a/docs/concepts/domains.mdx b/docs/concepts/domains.mdx index 110bbc0d94..424f4e1708 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..588e667be1 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 @@ -63,4 +77,99 @@ 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: + target: 3000 + mode: ingress + ``` + +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: + target: 3000 + mode: ingress + ``` + +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: + target: 3000 + mode: ingress +``` + +**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. From fe6ec8d4b068e0c9f6d0a6db714b8f8774bd88be Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 10 Dec 2025 01:29:29 +0000 Subject: [PATCH 3/5] Fix heading hierarchy in domains.mdx Co-authored-by: lionello <591860+lionello@users.noreply.github.com> --- docs/concepts/domains.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/concepts/domains.mdx b/docs/concepts/domains.mdx index 424f4e1708..79a31eb96d 100644 --- a/docs/concepts/domains.mdx +++ b/docs/concepts/domains.mdx @@ -85,11 +85,11 @@ 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. -### DNS Management Options +## DNS Management Options When bringing your own domain, you have two main approaches: -#### Option 1: Using Your Existing DNS Provider (CloudFlare, Namecheap, etc.) +### 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 have two choices: @@ -113,7 +113,7 @@ If you frequently deploy and tear down your services (e.g., for staging environm 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 +### 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. From 03a6834aaa68df725b17ffcde5dc4c965c081e4b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 10 Dec 2025 01:32:07 +0000 Subject: [PATCH 4/5] Fix YAML syntax to use array format for ports Co-authored-by: lionello <591860+lionello@users.noreply.github.com> --- docs/tutorials/use-your-own-domain-name.mdx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/tutorials/use-your-own-domain-name.mdx b/docs/tutorials/use-your-own-domain-name.mdx index 588e667be1..f80ccc7624 100644 --- a/docs/tutorials/use-your-own-domain-name.mdx +++ b/docs/tutorials/use-your-own-domain-name.mdx @@ -60,8 +60,8 @@ services: context: ./web dockerfile: Dockerfile ports: - target: 3000 - mode: ingress + - target: 3000 + mode: ingress ``` @@ -89,8 +89,8 @@ If you prefer to keep your DNS with your current provider (like CloudFlare or Na web: domainname: staging.example.com ports: - target: 3000 - mode: ingress + - target: 3000 + mode: ingress ``` 2. Deploy your service: @@ -115,8 +115,8 @@ This approach avoids having to reconfigure DNS and regenerate certificates for e services: web: ports: - target: 3000 - mode: ingress + - target: 3000 + mode: ingress ``` 2. Deploy your service: @@ -148,8 +148,8 @@ name: myapp-staging services: web: ports: - target: 3000 - mode: ingress + - target: 3000 + mode: ingress ``` **Or using the `--project-name` flag:** From d88d00cb98adadcdbeca5abc12ff0682f72d84cf Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 10 Dec 2025 01:34:34 +0000 Subject: [PATCH 5/5] Add protocol field to all port configurations for consistency Co-authored-by: lionello <591860+lionello@users.noreply.github.com> --- docs/tutorials/use-your-own-domain-name.mdx | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/docs/tutorials/use-your-own-domain-name.mdx b/docs/tutorials/use-your-own-domain-name.mdx index f80ccc7624..9ff6850857 100644 --- a/docs/tutorials/use-your-own-domain-name.mdx +++ b/docs/tutorials/use-your-own-domain-name.mdx @@ -60,8 +60,9 @@ services: context: ./web dockerfile: Dockerfile ports: - - target: 3000 - mode: ingress + - mode: ingress + target: 3000 + protocol: http ``` @@ -89,8 +90,9 @@ If you prefer to keep your DNS with your current provider (like CloudFlare or Na web: domainname: staging.example.com ports: - - target: 3000 - mode: ingress + - mode: ingress + target: 3000 + protocol: http ``` 2. Deploy your service: @@ -115,8 +117,9 @@ This approach avoids having to reconfigure DNS and regenerate certificates for e services: web: ports: - - target: 3000 - mode: ingress + - mode: ingress + target: 3000 + protocol: http ``` 2. Deploy your service: @@ -148,8 +151,9 @@ name: myapp-staging services: web: ports: - - target: 3000 - mode: ingress + - mode: ingress + target: 3000 + protocol: http ``` **Or using the `--project-name` flag:**