Skip to content

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-42 envs in two different companies, in two different regions, etc.).
  • Base zone — the platform's DNS zone (bcdock.io for production; dev.bcdock.io for 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/healthz for 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:

http://bcp-<shortId>.<location>.cloudapp.azure.com/<envName>/

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:

  1. 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.
  2. 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).
  3. The CLI talks to BC directly. bcdock env publish POSTs to https://<env>.bcdock.io/BC-dev/dev/apps over 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