URL shape¶
Every BCDock environment is reachable at https://<env-name>-<shortId>.bcdock.io/BC/. The URL shape is what makes wildcard TLS, agent-friendly endpoints, and cross-region resume tractable. This page summarises the design.
The hostname¶
https://my-test-env-a1b2c3d4.bcdock.io/BC/
^^^^^^^^^^^^^^^^^^^^^
env name
^^^^^^^^
env short ID
^^^^^^^^^^^
base zone
- Env name — DNS-safe, 3–40 chars. Customer-chosen at create time. Survives hibernation, resume, even cross-region moves. Becomes part of the URL.
- Short ID — 8 hex chars from the env's UUID. Disambiguates two envs with the same name (you can have
pr-42envs in two different companies, in two different regions, etc.). - Base zone — the platform's DNS zone (
bcdock.iofor production;dev.bcdock.iofor the dev stack). Wildcard TLS covers*.{zone}.
Wildcard TLS¶
We use a single wildcard certificate (*.bcdock.io) issued via Let's Encrypt's DNS-01 challenge. The challenge is solved by Traefik using Azure DNS as the provider — Traefik creates the _acme-challenge TXT record, waits for propagation, and the cert is issued.
Why DNS-01 instead of HTTP-01:
- One cert covers every env. HTTP-01 requires a per-host validation, which means a fresh cert per env name — not workable when env names are user-defined and ephemeral.
- Works across pool VMs. The cert isn't bound to one pool's IP; it covers the zone, so cross-region resume doesn't need a re-issue.
- No public HTTP listener required. The pool VMs only need port 443 open, not port 80.
The cert lives in core Key Vault (australiaeast — Sydney, per ADR-018); pools fetch it on first start and refresh on renewal.
Per-env DNS records¶
When a new env is created, two records get written into Azure DNS:
my-test-env-a1b2c3d4.bcdock.io. A <pool VM public IP>
my-test-env-a1b2c3d4.bcdock.io. TXT "BCDock managed; do not edit"
(The TXT is informational; we don't gate on it. It's there so a future operator running dig knows what they're looking at.)
When the env is deleted, the records are removed. When the env is hibernated and later resumed on a different pool (different region, autoscaler-rebalanced, etc.), the A record is updated to the new pool's IP. The customer's URL doesn't change.
Routing inside the pool¶
A pool's Traefik instance receives every HTTPS request on port 443, terminates TLS with the wildcard cert, and routes by Host(...) (and path, for the pool-agent route). Three classes of request land at three different backends:
| Host + path | Routes to |
|---|---|
<env>-<shortId>.bcdock.io/... |
The BC container's web client (/BC/) and dev/SOAP/REST endpoints |
<pool-host>.bcdock.io/pool-agent/... |
The pool agent's local HTTP server |
_acme-challenge.<zone> (TXT) |
Resolved during cert issuance via the DNS-01 provider, not via Traefik |
Inside each BC container, BC's HTTP listener (Traefik on the BC side, separate from the pool's Traefik) further routes by path:
| Path | Purpose |
|---|---|
/BC/ |
Web client (the default) |
/BC-dev/ |
Dev endpoint — bcdock env publish posts to BC-dev/dev/apps |
/BC-soap/ |
SOAP endpoint — Web Service Access Key auth |
/BC-rest/ |
OData / REST endpoint — Web Service Access Key auth |
The symmetric BC-{purpose} naming was added in 2026-05 (DEV-026) to make every BC interface reachable through the same URL and discriminator pattern. Before that, dev/SOAP/REST lived on different ports inside the container, which doesn't survive a Traefik reverse proxy in front.
Pool hostname¶
Pool VMs themselves are reachable at https://<pool-host>.bcdock.io/. This is used by:
- Platform → pool agent —
/pool-agent/...for container lifecycle calls - Operator SSH (for debugging) — port 22, not via Traefik, NSG-restricted
- Pool agent self-tests —
/pool-agent/healthzfor liveness probes
Customers don't normally see the pool hostname; their env URL is the per-env subdomain.
Local dev fallback¶
When AZURE_DNS_ZONE is unset (i.e. running scripts/local-e2e.sh against mock infra), there's no wildcard cert and no DNS records. Envs are reachable at the Azure FQDN with a path prefix:
No TLS (it's local dev), no per-env DNS, no Key Vault. Useful for the offline development loop; not used in production.
Why this shape matters¶
Three customer-visible consequences:
- URLs are stable. An env keeps its URL across hibernation, resume, even cross-region resume. The CNAME-then-A-record pattern means we update the pool IP behind the scenes; the customer's bookmarks keep working.
- One cert. Wildcard TLS at the zone level avoids cert-issuance gymnastics on every env create. New envs are reachable over HTTPS in seconds (DNS propagation + Traefik routing reload), not minutes (per-host cert issuance).
- The CLI talks to BC directly.
bcdock env publishPOSTs tohttps://<env>.bcdock.io/BC-dev/dev/appsover HTTPS — no PowerShell, no BcContainerHelper wrapper, no platform proxy. Exposing a clean BC URL was the prerequisite for the CLI's AL extension loop.
Read more¶
- Images and pools — pool VM model, autoscaler
- Reference → API keys — auth for the URLs above
- Guides → AL extension loop — concrete example of using the dev endpoint