Repository navigation
Description
Today Docker Compose serves everything over plain HTTP on localhost, and production TLS ends at a proxy or load balancer, as RUN.md says. This idea adds HTTPS to the compose stack as an option, without breaking a plain docker compose up. It isn't scheduled. It's for the four web templates only; Lambda runs behind API Gateway, so its emulator stays HTTP.
The two ways to do it
| Caddy in front (recommended) | Mount the .NET dev certificate | |
|---|---|---|
| How it works | An optional https profile adds a Caddy container that ends TLS with its own local certificate (tls internal) and forwards to each container over HTTP inside the Docker network |
Export dotnet dev-certs https to a .pfx, mount it into the app container, and set ASPNETCORE_URLS and Kestrel__Certificates__Default__* |
| Covers | Every container in the stack from one place: the app, the Aspire dashboard, the MCP Inspector and Open WebUI, for example on api.localhost, dashboard.localhost and so on |
Only the app. The dashboard, Inspector and Open WebUI stay HTTP |
| Matches production | Yes. The app stays on HTTP behind a TLS proxy and reads X-Forwarded-* with ASPNETCORE_FORWARDEDHEADERS_ENABLED=true, which is what RUN.md tells people to do |
No. Production doesn't serve TLS from Kestrel in the container |
| Setup per machine | None to start it. Trusting it means adding Caddy's root certificate (/data/caddy/pki/authorities/local/root.crt) to the OS once |
dotnet dev-certs https -ep … -p … before the first docker compose up, with a different mount path on Windows, macOS and Linux, and a password in the compose settings |
Same certificate as dotnet run |
No, it has its own root | Yes |
| Cost | One small container and a Caddyfile |
Some compose settings and a step in the docs |
Either way, the containers keep talking to each other over HTTP, and OTLP (4317 and 4318) stays as it is. Clients built on Node, such as Claude Code, VS Code, Cursor and the Inspector, don't read the OS certificate store by default, so they may still need the plain HTTP address.
Phase 1: Decide
- Caddy profile or dev certificate (leaning Caddy)
- Hostnames (
*.localhost) or one port per service, together with the port numbers decision - Whether
--include-authsolutions should default to it, for sign-in flows that insist on HTTPS
Phase 2: Build it
-
Caddyfileand thehttpsprofile in the four web templates, bound to127.0.0.1like the other ports - Forwarded headers on in the
dockerenvironment - RUN.md, the
docker-and-composeskill and each Run it locally page - Verify Template still creates a solution whose plain
docker compose upworks
Checks: the build pipeline passes, docker compose up still works with no setup, and docker compose --profile https up serves every container over HTTPS.
Activity