The proxy and subdomains

The Orchestrator forwards traffic to the right workspace container, HTTP and websockets alike.

Path routing

A workspace served at /acme/ has this mapping.

Request Goes to
/acme A redirect to /acme/
/acme/search The container's /search

Studio's front-end uses relative URLs and derives its API address from the page address, so nothing is rewritten in the HTML.

The proxy adjusts three things on the way:

  • Cookies: the workspace's Set-Cookie paths are re-scoped to /acme/, so workspaces on one host do not overwrite each other's msk-token.
  • Redirects: a Location header that points at an absolute path gets the /acme prefix.
  • Headers: X-Forwarded-For, X-Forwarded-Proto, X-Forwarded-Host and X-Forwarded-Prefix are added.

The Orchestrator's own session cookie is scoped to /api/, and the proxy strips it from anything it forwards.

Subdomain routing

With ORC_SUBDOMAIN_ROUTING on (the default), a workspace served at /aviation/ is also served at aviation.<anything>/. The first label of the host names the workspace, whatever follows it. One level only.

Request Goes to
https://example.com/aviation/search aviation's /search
https://aviation.example.com/search aviation's /search
https://aviation.workspaces.example.com/ aviation's /
https://example.com/, https://www.example.com/ The Orchestrator
https://nothing-by-this-name.example.com/ The Orchestrator (no such workspace)

On its subdomain a workspace is at the root, so paths are forwarded unchanged and no cookie or redirect is rewritten. Its cookies are host-only, so two workspaces never share one. Each workspace also gets an origin of its own, which matters for security.

Hosts that never match

An IP address, a single-label host such as localhost, the host of ORC_PUBLIC_ADDRESS and ORC_MANAGEMENT_HOST never name a workspace. That stops a workspace called workspaces from taking over workspaces.example.com when that is the Orchestrator's own address. Set ORC_PUBLIC_ADDRESS when the Orchestrator itself lives on a subdomain.

What it needs outside

  • A wildcard DNS record (*.example.com) pointing at the server.
  • A certificate that covers the wildcard. Let's Encrypt issues one certificate per workspace, see HTTPS and Let's Encrypt.
  • The self-signed certificate covers *.<host of ORC_PUBLIC_ADDRESS>. If an existing self.pfx does not, delete it and the Orchestrator makes a new one.

Locally, <slug>.localhost resolves to the loopback address in browsers and curl, so http://aviation.localhost:8080/ works with no setup.

To serve workspaces only under paths, set ORC_SUBDOMAIN_ROUTING=false. Then no wildcard record is needed and only one certificate is issued.

Reaching Docker containers

How the Orchestrator reaches a container depends on ORC_CONTAINER_ACCESS.

Value Behavior
port Publishes each workspace on 127.0.0.1:<random port>.
network Reaches each workspace by container name on the Docker network ORC_DOCKER_NETWORK.
auto (default) network inside a container, port otherwise.

Search engines

ORC_HIDE_FROM_SEARCH_ENGINES=true asks crawlers to leave the server and every workspace out. /robots.txt disallows everything on the host and on each <slug>. subdomain. Every response carries X-Robots-Tag: noindex, nofollow, replacing a workspace's own header. The landing page gets a robots meta tag. Well-behaved crawlers honor it, but it is not access control.