Skip to content

Filesystem Layout

MultiDocker keeps nothing in your project directories beyond the files you already committed. Its own state lives in two well-defined trees: one for the CLI, one for the app.

If you’re running from a clone, the tool itself is laid out like this:

multi-docker/
├── bin/mdocker CLI entry point (one large bash script)
├── lib/common.sh Shared bash lib (paths, config, registry, compose, port-check)
├── edge/ Traefik + Mailcatcher + dnsmasq + docker-socket-proxy
│ ├── compose.yml
│ ├── traefik/{traefik.yml, dynamic/{tls.yml, serverstransports.yml}}
│ └── docker-proxy/{nginx.conf, nginx.main.conf}
├── engine/ Generators + per-project subsystems
│ ├── detect.sh Profile heuristic
│ ├── render.sh Project override generator
│ ├── render-edge.sh Edge override generator
│ ├── terminal.sh tmux session manager
│ ├── git.sh Git snapshot
│ ├── share.sh Public demo tunnel
│ ├── profiles/*.yml Override templates
│ ├── shopware/*.sh Shopware verbs
│ └── db/*.sh DB dialect detection + dump/restore/shell/open
├── scripts/ Setup scripts (TLS, DNS, network, doctor)
└── macos-app/ SwiftUI front-end

Everything the standalone CLI creates lives here:

~/.config/multi-docker/
├── config.env BASE_DOMAINS, EDGE_NETWORK, optional EDITOR_CMD/EXEC_SHELL
├── registry.json Known projects (the source of truth)
├── overrides/
│ ├── <name>.override.yml profile-rendered override
│ ├── <name>.ports.yml port-conflict resolution (if any)
│ └── edge.override.yml multi-domain edge override
├── certs/
│ ├── wildcard.pem
│ ├── wildcard-key.pem
│ └── ca/{rootCA.pem, rootCA-key.pem} mkcert CA — never commit this
├── snapshots/
│ └── <project>/<service>-<ts>.sql.gz + <service>-latest symlink
└── state/
└── tunnels/<project>__<host>.{json,log} ephemeral share tunnels

The macOS app uses its own directory and its own runtime copy of the tool:

~/.multidocker/
├── bin/mdocker wrapper that resolves the "current" runtime
├── runtime/
│ └── <version>/ extracted runtime (bin, lib, engine, scripts, edge)
├── current → runtime/<v> symlink updated on install
├── config/ the app's config dir (registry, overrides, certs, …)
├── preferences/preferences.json
├── state/{wizard.json, .migrated-*}
└── logs/console-YYYY-MM.log rotating JSONL console log

The mkcert CA and wildcard cert live under config/certs/, deliberately outside the app’s runtime/<version>/ folder:

Older installs kept certs under edge/certs/; that path still exists for migration (ensure_certs_dir), but the live store is now the config directory.

Changing the base domain regenerates the derived files

Section titled “Changing the base domain regenerates the derived files”

Because overrides and certs are derived from the registry and config, changing the base domain via mdocker config set BASE_DOMAIN <new> regenerates the certificate, the resolver, every project override and the edge stack automatically. See Changing the Base Domain.