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-Cookiepaths are re-scoped to/acme/, so workspaces on one host do not overwrite each other'smsk-token. - Redirects: a
Locationheader that points at an absolute path gets the/acmeprefix. - Headers:
X-Forwarded-For,X-Forwarded-Proto,X-Forwarded-HostandX-Forwarded-Prefixare 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 existingself.pfxdoes 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.