← Start Here

START HERE FEATURE

Local Domain

A framework with tenancy should not be introduced through localhost forever. Register a stable local domain early and let the runtime behave like a product host.

Feature Guide

A quick orientation block that answers the essential questions: what this feature does, how it works, why it matters, and the key concepts behind it.

What this does

Register .test domains through the built-in local-domain helper instead of relying on ad hoc host setup.

Local Host Strategy

Make local URLs look like product hosts

Choose one `.test` base domain, register hosts through the Semitexa local-domain helper, and restart so the runtime resolves them predictably.

Step 1

Choose the base domain

Keep the local base memorable and stable. The common example is `semitexa.test`.

TENANCY_BASE_DOMAIN=semitexa.test

Step 2

Register the browser hosts

Register both the main host and any tenant-specific host you plan to open during local work.

bin/semitexa local-domain:add semitexa.test
bin/semitexa local-domain:add acme.semitexa.test
bin/semitexa local-domain:list

Step 3

Restart and open the host

After domain changes, restart once so the runtime, proxy, and DNS layer agree on the same environment.

bin/semitexa server:restart
http://semitexa.test

Why Not /etc/hosts?

  • The CLI-managed local-domain path is repeatable across projects and easier to inspect later with `local-domain:list`.
  • It keeps the local proxy and DNS story in the same operator surface instead of splitting it between shell scripts and OS edits.
  • It makes tenant hosts easier to add and remove as the project evolves.
TENANCY_BASE_DOMAIN bin/semitexa local-domain:add local-domain:list server:restart

Verified against Semitexa Ultimate 2026.10.03.1952

Local Domain

Serious tenancy work should happen on real local hostnames, not on endless localhost tabs.

A local domain is optional. A project works on http://localhost:<port> without one.

What it changes on your machine

Registering a .test domain reaches outside the project. Read this before you run it:

  • It needs sudo. You will be asked for your password.
  • It changes name resolution. In the default dns mode, on a system running systemd-resolved, it writes /etc/systemd/resolved.conf.d/semitexa-router.conf (sending *.test lookups to the router's DNS on 127.0.0.1:5553), may set DNSStubListener=yes in /etc/systemd/resolved.conf, restarts systemd-resolved and points /etc/resolv.conf at the systemd stub resolver. It asks before each of these when it has a terminal. In hosts mode it appends 127.0.0.1 <domain> # semitexa-router lines to /etc/hosts instead. bin/semitexa local-domain:mode shows or switches the mode.
  • It binds host port 80. The shared router containers (a proxy, plus a DNS container in dns mode) publish port 80, so nothing else on the machine can be listening there.
  • It records the domain in ~/.semitexa/router/registry/, shared by every Semitexa project on the machine.

bin/semitexa local-domain:remove <domain.test> removes a domain, including its /etc/hosts line.

Canonical flow

  1. Choose one stable .test base domain. Only .test is accepted.
  2. Put it in .env as TENANCY_BASE_DOMAIN, so the app builds tenant hosts and absolute URLs from it.
  3. Register the main host and any tenant hosts through the Semitexa helper.
  4. Restart the runtime so DNS, proxy, and environment agree on one shape.
  5. Open the real host in the browser.

Commands

In .env:

TENANCY_BASE_DOMAIN=semitexa.test

Then:

bin/semitexa local-domain:add semitexa.test
bin/semitexa local-domain:add acme.semitexa.test
bin/semitexa local-domain:list
bin/semitexa server:restart

Setting TENANCY_BASE_DOMAIN as a shell variable does nothing: the app container reads it from .env, and only picks up a change after server:restart.

Rules

  • prefer one memorable .test base domain per project
  • use the CLI helper instead of manual host drift
  • restart after meaningful DNS or environment changes
  • verify tenant hosts in the browser, not only the raw port

Why this matters

Tenancy, cookie scope, domain routing, and absolute URL behavior become much easier to reason about when local development already behaves like a real product host.

Practical Rules

Keep local domain work boring and consistent

The point of local domains is to reduce ambiguity, not to create a custom networking hobby project.

Prefer one `.test` base domain per project instead of mixing many local suffixes.

Register domains with `bin/semitexa local-domain:add` and remove stale ones with `bin/semitexa local-domain:remove`.

Restart after meaningful DNS or `.env` changes so the runtime shape stays coherent.

Open the real host in the browser once local DNS is in place, not only `localhost:9502`.

Support Semitexa
Built for developers who prefer control over magic. Your support helps keep it fast, open, and evolving.

Donate via PayPal