Every container on DoCatz gets a name of its own, served over HTTPS, with nothing to publish and no port to remember.
And every compose project can have its own .env in DoCatz — the values its containers get — without touching the
project’s .env file. This page explains both.
The settings live in Settings → Domains. The cards there wear the badge Shared with Catzoid apps: DevCatz and DoCatz use the same domain ending, the same local certificate authority and the same port forwarding, so you set them up once, in either app.
A name for every container
| Container | Its address |
|---|---|
| A service of a compose project | https://<service>.<project>.docatz.<ending> — for example https://web.shop.docatz.localhost |
| Any other container | https://<container name>.docatz.<ending> |
Names are lowercased, and anything that is not a letter, digit or dash becomes a dash: the service Web_App in the
project my shop is web-app.my-shop.
Nothing needs publishing. DoCatz runs a small router on its engine (an nginx:alpine container called
docatz-router, hidden from the list) that reaches each container on its own network address. It picks the port the
container really listens on over the one its image declares, prefers common web ports (80, 8080, 3000, 8000, 5173,
4321, 5000, 4200, 8888, 4000, 9000, 443, 8443), skips debugger and admin ports such as 2019, 9003 and 9229, and falls
back to 80. WebSockets pass through, so hot reload works.
A name answers while its container runs. For a name with no running container behind it, the browser shows Nothing runs at <host> — No running container has this name. Start it in DoCatz.
Which containers get a URL
A container gets a URL when it has an address DoCatz can reach — its own IP on a Docker network (every compose service has one) or a published TCP port — and at least one of its ports could be a web page.
Databases, caches, mail servers and message queues get no URL: when every TCP port a container exposes is one of the
known non-web ports — such as 5432 (PostgreSQL), 3306 and 33060 (MySQL), 6379 (Redis), 27017 (MongoDB), 5672
(RabbitMQ), 1025 (a mail catcher’s SMTP) — DoCatz shows its inner address instead, like postgres:5432: Not a web
page: the other services of its project reach it at this address. A container that exposes a web port next to one of
those still gets a URL — Mailpit, for example, opens at its web UI on 8025.
A container that exposes no port at all still gets a name (DoCatz tries the port it listens on, or 80). A container on
the host network has no address of its own, so it gets none.
Settings → Domains says Every container that publishes a port for short; DoCatz names the containers that publish nothing too.
Databases on this computer
A database container — PostgreSQL, MySQL, MariaDB, Redis, Valkey, MongoDB, Elasticsearch or OpenSearch — gets an
address on this computer instead of a URL: 127.0.0.1:<port>, for DBCatz, a database app or a script. Nothing is
published and your compose file does not change: DoCatz forwards the port to the container.
- The port is the engine’s own plus 10000 — 15432 for PostgreSQL, 13306 for MySQL and MariaDB, 16379 for Redis and Valkey, 37017 for MongoDB, 19200 for Elasticsearch — or the next free one when that is taken.
- It stays with the container’s name (
<project>/<service>), so it is the same after a restart and a saved connection keeps working. - A port the container publishes itself wins.
The container’s page shows the address next to its name, with Open in DBCatz — see DBCatz.
Change a name
On a container’s Info tab (Edit next to Domain) or a project’s Domains tab, change the part before
.docatz. Save keeps it, Default goes back to the service.project name, Cancel leaves it. A changed name
gets a custom badge.
- A name is letters, digits and dashes; dots make sub-names, such as
api.shop. - Leave
.docatzand the ending out — the ending always follows Settings → Domains. - Two containers cannot share a name: <name>.docatz.<ending> is already another container’s name.
The default domain
Settings → Domains → Default domain → Ending is the last part of every name. It starts as DevCatz’s ending when
DevCatz is installed, and localhost otherwise.
.localhostalways points at this computer in browsers, so it needs nothing else.- Another ending, such as
test, needs a resolver (below). - Endings that are real or reserved on the internet are refused —
com,net,org,io,dev,appandlocal: pick localhost or test. An ending another tool already resolves is refused too.
Change it in DoCatz or DevCatz and both follow.
DNS for other endings
On a Mac, .localhost needs no DNS. For another ending, the Resolver row has Install…: DoCatz creates
/etc/resolver/<ending> (marked Managed by DevCatz, the same file DevCatz makes) that sends those names to a tiny
DNS server on 127.0.0.1 port 53531, which answers every name with this Mac. macOS asks for your administrator
password once. Remove… takes the file away again.
If /etc/resolver/<ending> belongs to another tool, DoCatz leaves it alone: Remove that tool’s resolver first.
On Windows only browsers resolve *.localhost by themselves, so other programs — curl, your API client, a
container calling another — need help even for .localhost. The row Register the names with Windows has
Register…: DoCatz adds Windows DNS rules (NRPT, labelled DevCatz) that send .localhost and your ending to a
tiny DNS server on 127.53.0.1:53, which answers with this PC. Windows asks for administrator approval once.
Remove… takes the rules away again.
If port 53 on that address is taken, the message says what holds it — Mobile hotspot (Internet Connection Sharing) or Docker Desktop are the usual ones.
The DNS server is shared with DevCatz on the same address: whichever app runs answers for both. If DevCatz already holds the port, DoCatz runs none.
HTTPS
DoCatz serves names over HTTPS with certificates from one local certificate authority, Catzoid Local CA, shared by the Catzoid apps. DoCatz uses the CA already in the shared settings, or DevCatz’s existing one, and only makes a new one when there is none. Each name gets its own certificate, made on the spot and renewed by itself.
Settings → Domains → HTTPS certificates:
- Trust the certificate — Trust… adds the CA to your login keychain — macOS asks for your password or Touch IDyour Trusted Root certificates — Windows asks “install this certificate?”. When it is done: Certificate trusted — reload your browser tabs. Remove… takes the trust away. If DevCatz already trusted it, there is nothing to do.
- Serve container domains over HTTPS — DoCatz’s own switch, on by default. Off serves the names over plain HTTP.
The CA’s private key never leaves this computer. More about it in Security.
Names without a port
DoCatz’s proxy listens on this computer only, on port 8743 for HTTPS and 8780 for HTTP. Until you turn on
names without a port, URLs carry the port: https://web.shop.docatz.localhost:8743.
Settings → Domains → URLs without a port → Names without a port forwards ports 443 and 80, so the URL needs no port. macOS asks for your administrator password once.Windows asks for administrator approval once. The steps are Check ports 443 and 80, Forward ports 443 and 80, and Check that names answer without a port — then Names without a port are on.
On a Mac the forwarding is two small system services (com.mrcatz.herd.forward-https and -http in
/Library/LaunchDaemons) that pass ports 443 and 80 on to the proxy.
On Windows the forwarding is netsh interface portproxy rules, and the IP Helper service is set to start
automatically, because it carries them.
These are the same system pieces DevCatz installs, so there is only ever one of each on a computer. DoCatz drops the
:8743 from its URLs only once it has checked that a request through port 443 really reaches it; it checks again
every 10 seconds.
When DevCatz is installed too
- DevCatz installed and running — ports 443 and 80 go to DevCatz’s proxy, so its sites keep working, and DevCatz
hands every
*.docatz.<ending>name on to DoCatz. - DevCatz installed but closed — DoCatz stands in on DevCatz’s ports, so its own names keep answering. A DevCatz site then shows <host> is a DevCatz site — Open DevCatz to serve it. DoCatz answers here only for its own names while DevCatz is closed. DoCatz steps back within about two seconds of DevCatz starting.
- DevCatz not installed — the forwarding goes straight to DoCatz’s proxy.
When nothing answers on port 443, the card says so, and DoCatz’s names keep their :8743 until the app behind the
forwarding is open again. An older DevCatz that cannot hand the names on yet gives DoCatz’s names keep their :8743
until DevCatz is updated to hand them on.
When you uninstall DoCatz, the forwarding and the resolver stay as long as another Catzoid app still uses them.
A project’s own .env in DoCatz
A project’s .env is written for your computer: DB_HOST=127.0.0.1, REDIS_URL=redis://localhost:6379. Inside a
container, 127.0.0.1 is the container itself, so those values do not work there. DoCatz solves it the way a deploy
platform does: each compose project can have its own .env in DoCatz — the values its containers get when DoCatz
runs them, with hosts like postgres instead of 127.0.0.1. The project’s own .env stays exactly as it is, for
DevCatz and your tools on this computer.
Open it from a project’s Environment tab, or the key icon (.env in DoCatz) on its row in the list.
Create it
The first time it says <project> has no .env in DoCatz yet, with:
- Start from .env — a copy of the project’s
.env, - Start from .env.example (or
.env.dist,.env.sample, whichever the project has), - Start empty.
When it copies a file, DoCatz points the hosts on this computer at where a container finds them:
- keys ending in
_HOSTset to127.0.0.1,localhostor::1, - keys ending in
_URL,_URIor_DSNwhose address is on those hosts and whose scheme is a database, cache, queue or mail server —mysql://,postgres://,redis://,mongodb://,amqp://,smtp://,nats://,memcached://and their variants.
Each one goes to the project’s own service of that kind when the compose file runs one — DB_HOST=127.0.0.1
becomes DB_HOST=postgres when there is a postgres service, and a URL gets that service’s inner port — or else to
host.docker.internal, which is your computer as seen from a container (the port stays). Keys starting with
APP_, ASSET_ or VITE_ are never changed: they are the addresses a browser uses. A comment at the top of the file
lists the keys DoCatz pointed.
Edit it
The file is locked by default: values are hidden and editing is off. Unlock shows them and lets you edit; Lock hides them again. The file is kept in DoCatz’s data folder, readable by you only, never in the project.
- Save (mod+S) and Revert; the footer counts the variables and says locked: values hidden, editing off or unsaved changes.
- Mistakes are flagged: Line 12: not KEY=value, or DB_HOST is set twice (lines 3 and 9); the last one wins.
- If the file changed elsewhere since you opened it: The .env changed since you opened it: reload it first.
How it reaches the containers
Whenever DoCatz runs the project — Build & Up, Up and the other compose buttons, or the compose editor — every
service gets this .env, on top of the project’s own. Keys the compose file sets under environment: always win over
any .env. DoCatz also applies the same host pointing to the project’s own .env on every run, so a value you did
not copy still reaches the right host.
On Windows, services that get host.docker.internal also get it as an extra host pointing at the PC, because Docker
in WSL has no such name by itself. A service on your PC that listens on 127.0.0.1 only is usually out of a container’s
reach: let it listen on all addresses.
A container keeps the values it was created with. After you change the .env, DoCatz says which containers do not
have these values yet and offers Build & Up to recreate them. (It compares the names it expects with what the
containers have; it never shows values there.)
A docker compose up you start yourself in a terminal uses the project’s .env only.
The .env and DevCatz
DevCatz’s Docker tab knows this file. When it runs a site’s
compose file on DoCatz, its Environment: line says whether the containers get DoCatz’s .env of the project (and
whether it differs from the project’s), or the project’s .env. DevCatz never replaces DoCatz’s .env on its own.
Last updated 2026-11-03