> For the complete documentation index, see [llms.txt](https://docs.hivel.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hivel.ai/self-managed-hivel-deployment/virtual-private-cloud/aws/dns-setup-aws/setup-and-prerequisites/recommended-option-a-domain-+-lets-encrypt.md).

# Recommended: Option A - Domain + Let's Encrypt

DNS Setup (AWS)

### When to Use This Option?

Choose this option when you have (or can obtain) a domain. Caddy automatically obtains and renews a trusted Let's Encrypt certificate with no manual management.

### Step 1: Point DNS at Your Domain

**Goal:** Make your subdomain resolve to the VM's public IP.

**In AWS Console (Route53):**

1. Go to Route53 > Hosted Zones
2. Select your domain.
3. Create a new A record:

| Record Type | Name                  | Value           |
| ----------- | --------------------- | --------------- |
| A           | hivel.yourcompany.com | \<vm-public-ip> |

**Recommendation:** Use an Elastic IP for the VM so the address doesn't change on instance restart.

**Wait for DNS propagation** (a few minutes), then verify.

{% code expandable="true" %}

```
# Replace hivel.yourcompany.com with your actual domain.

dig +short hivel.yourcompany.com
```

{% endcode %}

**Expected result:** Command returns your VM's public IP address.

### Step 2: Open Required Ports

**In AWS Console (EC2 Security Group):**

1. Go to EC2 > Security Groups
2. Select your VM's security group
3. Add these inbound rules:

| Type       | Port | Source                             | Purpose                                                |
| ---------- | ---- | ---------------------------------- | ------------------------------------------------------ |
| Custom TCP | 80   | 0.0.0.0/0                          | Let's Encrypt HTTP-01 certificate validation challenge |
| Custom TCP | 443  | 0.0.0.0/0, or your office/VPN CIDR | HTTPS traffic to the UI                                |

**Important:** Port 80 must be reachable from the public internet for certificate issuance to succeed, even though all application traffic will use HTTPS.

### Step 3: Configure and Start Caddy

**On the VM:**

Replace `hivel.yourcompany.com` with your actual domain in all commands below.

Create the Caddy configuration file:

```
mkdir -p ~/caddy && cd ~/caddy

cat > Caddyfile <<'EOF'
hivel.yourcompany.com {
    reverse_proxy localhost:3000
}
EOF
```

Start the Caddy container:

```
docker run -d --name caddy --restart unless-stopped --network host \
  -v $(pwd)/Caddyfile:/etc/caddy/Caddyfile \
  -v caddy_data:/data \
  caddy:2
```

**What this does:**

* `--network host` allows Caddy to reach the UI container via localhost:3000 without additional Docker network configuration
* `-v caddy_data:/data` persists certificates across container restarts

**Expected result:** `docker ps | grep caddy` shows the Caddy container as Up.

**If it fails:** See Certificate Not Issued in [Troubleshooting](/self-managed-hivel-deployment/virtual-private-cloud/aws/dns-setup-aws/troubleshooting.md).

### Step 4: Verify the Setup

**On the VM, check Caddy logs:**

```
docker logs -f caddy
```

**Wait for the success message:** Look for a line confirming `certificate obtained successfully`.

**In your browser, navigate to:**

```
https://hivel.yourcompany.com
```

**Expected result:** The page loads and the browser shows a trusted certificate with no warnings.

**If it fails:** See Certificate Not Issued in [Troubleshooting](/self-managed-hivel-deployment/virtual-private-cloud/aws/dns-setup-aws/troubleshooting.md).

**Next step:** HTTPS setup is complete. Your Hivel UI is now securely accessible at `https://hivel.yourcompany.com`.

For ongoing Caddy management (restart, stop, view logs), see [Managing the Caddy Container](/self-managed-hivel-deployment/virtual-private-cloud/aws/dns-setup-aws/managing-the-caddy-container.md).

<br>

{% columns %}
{% column %} <a href="/self-managed-hivel-deployment/virtual-private-cloud/aws/dns-setup-aws/setup-and-prerequisites.md" class="button primary" data-icon="backward">Back to Setup and Prerequisites</a>
{% endcolumn %}

{% column %}

{% endcolumn %}

{% column %} <a href="/self-managed-hivel-deployment/virtual-private-cloud/aws/dns-setup-aws/setup-and-prerequisites/advanced-temporary-option-b-no-domain-yet-self-signed.md" class="button primary" data-icon="forward">Option B: Self-Signed</a>
{% endcolumn %}
{% endcolumns %}
