Harthelm Docs
Concepts

URLs and routing

Dev URLs, ports and routes, private and public, managed services' hosts, and custom domains.

Last updated 2026-10-19

Every workspace gets addresses for its landscape without any setup: the dev URL, and one host per public port. Your own host names come in front through custom domains.

The dev URL

https://<id>-3000.<workspace domain>

<id> is the workspace's id. The 3000 is part of the host name, not a port of yours: the dev URL carries the routes of all services, whatever ports they listen on. The Run panel links each route, and the workspace list shows the address in its URL column.

Routes

A service's ports list the routes of the dev URL that go to them:

harthelm.yml
services:
  web:
    type: steps
    steps: [{run: npm start}]
    ports:
      - port: 3000
        routes: [{path: /}]
  api:
    type: steps
    steps: [{run: ./api}]
    ports:
      - port: 8080
        routes: [{path: /api, strip: true}]
  • The longest prefix wins, on whole path segments: /api matches /api, /api/ and /api/items, not /apix. / matches everything else.
  • strip: true removes the prefix: /api/items reaches api as /items. The query string stays.
  • Route paths are unique in a landscape.
  • A forward service's routes send paths to an address outside the landscape.

Public ports

A port with public: true also gets a host of its own that sends every path to that port:

https://<id>-<port>.<workspace domain>

Public ports are unique in a landscape and cannot be 3000.

Internal services

A service with neither routes nor a public port has no address outside the workspace. The other services of the landscape reach it as ws-<id>-<name>:<port>.

Private and public

Workspace addresses are private by default: a browser must be signed in as a member of the team, and a script sends an API key in the Harthelm-Authorization header. Harthelm removes that header before the request reaches your app. See Private apps.

A workspace created with Visibility Public lets anyone with the link open its app address.

Managed services' hosts

RabbitMQ brokers and S3 stores of your team have a host of their own Since 1.4.0:

https://ms-<n>.<workspace domain>

<n> is the instance's number. A broker's host serves RabbitMQ's management UI, always behind the team's sign-in; a store's host serves its S3 API, behind the sign-in or public. See Managed services › From a browser.

Custom domains

A team admin adds a host name such as shop.example.com to the team, proves ownership with a DNS TXT record and points the name at the installation. Then routes send paths of the domain to one or more of the team's workspaces:

  • Routes are checked in order and the first match wins. A path matches itself and everything below it.
  • The path reaches the workspace unchanged.
  • Several workspaces on one route split the visitors evenly; each visitor stays with theirs for 24 hours.
  • A domain is public unless Team members only is set.
  • Harthelm requests and renews a certificate, or you upload your own.

See Custom domains and Path routing and split traffic.

Sleeping services

A request to a sleeping service wakes it, and every service it needs. The router holds the request until they are ready, usually a few seconds. A service that is not ready gets no traffic.

Next steps

On this page