Skip to content

Real Caddy resolution

Cadder does not embed Caddy. The daemon resolves and pins one Caddy executable when it starts. Project registration never changes the selected executable.

The daemon uses this exact order:

  1. An absolute --real-caddy daemon-start override.
  2. caddy.real_command or caddy.real_path in cadder.toml beside the Cadder executables.
  3. [caddy] in the standard per-user file.
  4. The same configuration in the system file.
  5. A native executable named caddy on PATH that is not Cadder’s shim.

An invalid higher-priority value stops resolution. Cadder does not hide a broken configuration by selecting a lower-priority executable.

Project files, registration working directories, CADDER_CADDY_REAL_COMMAND, and shim options do not participate in this chain.

real_command names one program resolved through PATH; it cannot include arguments or a path. real_path is an absolute path. In either case, Cadder canonicalizes the selected executable and requires a regular native executable. Windows batch scripts and a final reparse point are rejected; Unix executables require an executable mode bit.

Cadder does not require a special owner, parent-directory permission layout, or hardened ACL for the Caddy executable or configuration file. Normal Scoop, package-manager, system, and user-local installations are valid inputs. Runtime image pinning, described below, detects replacement after selection.

Cadder accepts Caddy 2.11.3 or newer within the 2.x release line. The selected build contains the standard modules used by Cadder and passes the compatibility probe shipped with the Cadder release.

The daemon pins the executable’s canonical path, source, operating-system file identity, SHA-256 digest, semantic version, module inventory, and probe revision. It verifies the pinned image again before every probe, adaptation, runtime start, reload, and stop operation. Metadata output is bounded and each metadata command has a 30-second deadline.

On Windows, Cadder retains a read-only handle without write or delete sharing for the daemon lifetime. Stop the daemon before replacing or upgrading the selected Caddy executable. If the path, identity, or content changes while the daemon runs, Cadder rejects the operation and reports that the pinned image no longer matches.

PATH fallback ignores empty and relative entries. It checks only the platform-native caddy filename and skips candidates that are not native executables. A configured command checks only its configured program name.

Cadder compares operating-system file identity, not just path text, when excluding its shim. A symlink or hardlink to Cadder’s caddy shim is therefore skipped even when it appears at another path.

The shim does not accept a real-Caddy selector. caddy run attaches only to the running Cadder daemon; it never starts an unmanaged Caddy process as recovery.

Read-only inspection commands such as caddy version, caddy adapt, and caddy validate use the same portable/per-user/system/PATH resolver. Their stderr notice identifies the output as real-Caddy inspection rather than Cadder runtime state.

If resolution fails, the error names the rejected source and the action that restores a working setup.