Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 127 additions & 4 deletions src/content/blog/ddev-local-trusted-https-certificates.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
title: "DDEV Trusted HTTPS Certificates"
pubDate: 2019-05-23
modifiedDate: 2025-11-15
modifiedComment: Updated to explain Certificate Authorities, how mkcert installs the local CA, and troubleshooting steps for when automatic installation doesn't work. Added reference to detailed browser configuration documentation.
modifiedDate: 2026-03-28
modifiedComment: Added WSL2 two-computer model explanation, CAROOT/WSLENV propagation, Firefox variant trust store caveats, and ddev utility tls-diagnose reference.
summary: The importance of local HTTPS, and how to take advantage of it with DDEV.
author: Randy Fay
featureImage:
Expand All @@ -25,6 +25,8 @@ You don't have to read or understand the rest of this :) There's a one-time inst
mkcert -install && ddev poweroff && ddev start
```

**WSL2 users:** the setup is a bit different — [see the WSL2 section below](#wsl2-the-two-computer-model).

## Understanding Certificate Authorities

When you visit an HTTPS website, your browser verifies that the site's SSL/TLS certificate was issued by a trusted **Certificate Authority (CA)**. A CA is an organization that validates website identities and issues digital certificates confirming they are who they claim to be. Your operating system and browsers come with a list of trusted CAs (like Let's Encrypt, DigiCert, or Sectigo).
Expand Down Expand Up @@ -68,14 +70,119 @@ mkcert -install

**Windows**: Run `mkcert -install` and accept the dialog that pops up.

## Troubleshooting
**WSL2**: See the [WSL2 section below](#wsl2-the-two-computer-model) — the setup is more involved.

## WSL2: The Two-Computer Model

WSL2 is where most HTTPS trust problems originate, so it's worth understanding what's actually happening.

When you use DDEV on WSL2, you're working with two separate environments:

- **Linux (WSL2)**: where DDEV runs, Docker runs, and your project files live
- **Windows**: where your browser runs (Chrome, Edge, Firefox)

These two environments do **not** share a certificate trust store. The Linux side and the Windows side each have their own. When your Windows browser visits `https://myproject.ddev.site`, it checks the **Windows** certificate store — it has no knowledge of anything installed on the Linux side.

This means `mkcert -install` run inside WSL2 only installs the CA into the Linux trust store. Your Windows browser never sees it, and you get certificate warnings.

:::tip[The DDEV Windows installer handles all of this]
The normal way to set up DDEV on WSL2 is to run the [DDEV Windows installer](https://ddev.com/get-started/). It performs every step below automatically, and can be run again at any time to repair a broken configuration. The manual steps that follow are for understanding what the installer does, or for recovering from an unusual situation.
:::

### The Correct WSL2 Setup

The solution is to keep the mkcert CA on the **Windows** filesystem and share it into WSL2:

1. **Install mkcert on Windows** and run `mkcert -install` from PowerShell (not from WSL2). This puts the CA into the Windows certificate store where Chrome and Edge can find it.

2. **Set `CAROOT` and `WSLENV`** so WSL2 uses the Windows CA instead of creating its own. From PowerShell:

```powershell
$env:CAROOT = mkcert -CAROOT
setx CAROOT $env:CAROOT
$env:WSLENV = "CAROOT/up:$env:WSLENV"
setx WSLENV $env:WSLENV
```

The `CAROOT/up` flag in `WSLENV` tells WSL2 to inherit the `CAROOT` variable from Windows and translate the path (e.g., `C:\Users\you\AppData\Local\mkcert` becomes `/mnt/c/Users/you/AppData/Local/mkcert`).

3. **Restart WSL2** so the environment variable takes effect:

```powershell
wsl --shutdown
```

4. **Verify** inside WSL2:

```bash
echo $CAROOT
# Should show something like /mnt/c/Users/you/AppData/Local/mkcert
```

5. **Run `mkcert -install` inside WSL2** to register the Windows CA with the Linux system trust store as well (needed for `curl` and other Linux tools).

6. **Restart DDEV**: `ddev poweroff && ddev start`

### Exception: Browser Running Inside WSL2 via WSLg

A small number of WSL2 users run their browser **inside** WSL2 using [WSLg](https://github.com/microsoft/wslg) (the Linux GUI app support built into modern Windows). If your browser is launched from inside the WSL2 terminal rather than from the Windows Start menu or taskbar, you're in this category.

In that case, the browser is a Linux process and uses the Linux trust store — the Windows certificate store is irrelevant. The setup is the same as on a regular Linux machine: run `mkcert -install` inside WSL2 and you're done. The `CAROOT`/`WSLENV` setup described above is not needed.

This is uncommon. If you're not sure which case applies to you, you're almost certainly running a Windows browser.

### Why `CAROOT` Must Point to the Windows Filesystem

DDEV generates per-project certificates by calling `mkcert --cert-file ... hostname`. For those certificates to be trusted by Windows browsers, they must be signed by the CA that Windows trusts — which is the one installed on the Windows side.

If `$CAROOT` points to a Linux path (e.g., `/root/.local/share/mkcert`), DDEV will sign certificates with a Linux-only CA. Your Windows browser will reject them.

If HTTPS doesn't work after installation, here are common issues:
You can always check where `CAROOT` is pointing:

```bash
mkcert -CAROOT
# Should start with /mnt/c/...
```

### Firefox on Windows

Firefox on Windows is a special case. Unlike Chrome and Edge, Firefox does **not** use the Windows system certificate store. It maintains its own trust store, so even a correctly configured CAROOT won't automatically make Firefox trust DDEV certificates.

To use DDEV with Firefox on Windows, you must manually import the CA:

1. Find the CA file: it's `rootCA.pem` inside the directory shown by `mkcert -CAROOT` (translated to a Windows path, e.g., `C:\Users\you\AppData\Local\mkcert\rootCA.pem`)
2. In Firefox: **Settings → Privacy & Security → View Certificates → Authorities tab → Import**
3. Import `rootCA.pem` and check "Trust this CA to identify websites"

Firefox Nightly, Developer Edition, and ESR each maintain a **separate** trust store from standard Firefox. If you use any of these, repeat the import for each one.

### Diagnosing WSL2 Certificate Problems

DDEV v1.25.2 and later include a built-in diagnostic tool that checks every part of the certificate trust chain:

```bash
ddev utility tls-diagnose
```

It checks:

- `mkcert` installation and `CAROOT` path
- Whether `CAROOT` points to the Windows filesystem
- Whether `WSLENV` is configured correctly
- Whether the mkcert CA is in the Windows certificate store
- Whether your project certificates are valid and signed by the current CA
- Whether Chrome/Edge would actually trust a live HTTPS request (via PowerShell `Invoke-WebRequest`)

Run this first when something isn't working.

## Troubleshooting

### Browsers Still Show Warnings

Some browsers don't automatically pick up the system trust store. Firefox, in particular, maintains its own certificate store. Run `mkcert -install` which should handle Firefox, but if issues persist, see the [browser configuration documentation](https://docs.ddev.com/en/stable/users/install/configuring-browsers/).

**WSL2 users**: run `ddev utility tls-diagnose` — it will tell you exactly what's wrong and how to fix it.

### cURL Doesn't Trust Certificates

If you're using an unusual cURL that doesn't respect your system's trust store, you may need to:
Expand All @@ -92,6 +199,22 @@ The `curl` inside DDEV's web container is already configured to trust DDEV certi

Occasionally, OS updates can remove trusted CAs. If you start seeing certificate warnings after an update, run `mkcert -install` again to reinstall the local CA.

### Nuclear Option

When something is deeply broken — wrong CA, mismatched certificates, or an unknown state — start fresh:

```bash
ddev poweroff
mkcert -uninstall
rm -rf "$(mkcert -CAROOT)"
mkcert -install
ddev start
```

:::warning[WSL2 users]
Run `mkcert -install` from Windows PowerShell (to update the Windows certificate store) **and** from inside WSL2 (to update the Linux trust store). Then restart DDEV.
:::

### Manual Certificate Installation

If automatic installation doesn't work, you can manually install the CA certificate. Find it with:
Expand Down
Loading