Configuration and CLI compatibility contract¶
Status: 1.0 compatibility contract. This reference retains the CLI/YAML choices approved for 0.0.80 on 2026-09-27. HTTP, metrics and journal contracts have their own references. See the release notes for the validation record and its limits.
Use full option names and explicit selectors in automation. Global options go before the subcommand; that subcommand’s options go after it:
monit-docker -c config.yml --name 'web-*' stats --rsc status
monit-docker -c config.yml check-config --output json
monit-docker -c config.yml run web-guard --dry-run
Configuration source and precedence¶
-c FILEselects a file; otherwise useMONIT_DOCKER_CONFFILE, then/etc/monit-docker/monit-docker.yml.If the selected path exists, load it. A read or parse error does not fall back to the environment.
If it does not exist, use nonempty
MONIT_DOCKER_CONFIGas inline YAML.Without either source, historical
stats,monit,cronandserveuse an empty configuration.check-config,runandscenarioinstead return 110.
The root must be a YAML mapping. {} is valid; an empty document, null or a
list is not. The checked loader requires string keys and mapping-valued sections.
It rejects unknown sections and entry fields. Every monitoring command validates all configured aliases and scenarios, including
dormant entries, before Docker access. Configuration errors return 110. The file
is rendered once; runtime and offline checks use the same validation. See the
beta change notice before upgrading.
Section |
Entry structure |
Meaning |
|---|---|---|
|
Mapping |
Template context, not a mapping of CLI defaults |
|
Mapping |
Shared template variables |
|
|
Docker SDK connection options; |
|
|
Nonempty list of |
|
|
Nonempty absolute container paths; |
|
|
Nonempty list of conditions combined with AND |
|
|
Nonempty ordered action sequence |
|
Mapping |
|
|
Mapping |
|
|
Mapping |
|
|
Mapping |
Defaults for direct |
|
|
A named |
These direct command sections are available since 1.3.0. Each command
reads its own section. Explicit flags override individual YAML fields, even at
their built-in default value. Repeating --rsc or --cmd / --cmd-if replaces
the complete YAML list in argument order. For monit, choosing --rsc also
discards configured commands and their exit-code policy for that invocation.
Choosing --cmd discards configured resources. Use --no-propagate-exit-code
to override propagate_exit_code: true. Simulation is requested with the
--dry-run flag. Global selectors still go before the subcommand. Named
scenarios keep their own settings.
Command/condition aliases and directory-group names use an ASCII letter followed
by at most 64 letters, digits, underscores, dots or hyphens. Scenario names match
[a-z0-9][a-z0-9-]{0,63} and are selected exactly. Client and container-group names
have no equivalent restrictive naming pattern in the checked loader, but must
be nonempty strings. Prefer simple printable names.
Entries may have local vars and @import_vars. Section imports use
@import_client, @import_ctn-group, @import_dir-group, @import_condition,
@import_command or @import_scenario; accept one path or a nonempty list. Imported
files contain entries directly, without repeating the section wrapper. Relative
imports resolve against the main file’s directory (the working directory for
inline configuration). Later imports override earlier entries; main-file entries
override imported entries as a whole, without deep merging. Imports are not
a recursive include mechanism.
Mako templates run during rendering and must be trusted. They can access ENV,
the my YAML helper and the supplied context. An imported file is rendered before
its entry-local variables are available. Offline validation does not sandbox
template execution. State/audit paths resolve against the working directory,
not the configuration directory; absolute paths are preferable for scheduled jobs.
Directory access identities contain exactly uid, gid and groups: integer
IDs from 0 through 4294967294, and 1..128 distinct supplementary group IDs including
gid. Booleans are not IDs. Paths cannot contain ASCII control characters;
duplicates are removed in order. Access probes require Python 3 in the target
Linux container; see access checks for runtime restrictions.
Docker client selection¶
--client-from-env takes precedence over --client and configured clients.
Otherwise, --client NAME selects an entry, or the first loaded client is used.
With no configured clients the historical runtime uses Docker environment
settings, defaulting DOCKER_HOST to unix:///var/run/docker.sock when absent.
An explicitly named unknown client is always rejected, even if --client-from-env
is also supplied. With a known name, --client-from-env still selects the environment.
Container selectors¶
Input |
Current behavior |
|---|---|
|
Repeatable; one pattern per value, surrounding whitespace removed; commas are never separators |
Several patterns or kinds |
OR: any name, ID, image tag or label value can select the container |
|
Repeatable status alternatives, applied in addition to the pattern selection |
|
Repeatable exact group names; their patterns form a union, intersected with the union of direct name/ID/image/label patterns when supplied |
No patterns/groups |
All containers allowed by the status filter, including stopped containers |
Ordinary pattern |
Case-sensitive shell-style glob, matching the whole value |
|
Case-sensitive Python regular expression matched from the start; add |
12-character alphanumeric ID pattern |
Automatically gets a trailing |
Label pattern |
Matches label values, not keys or Docker’s |
Image pattern |
Matches image tags, not image IDs/digests |
Quote patterns to prevent shell expansion. Repeat options for several patterns:
--name 'web-*' --name 'api-*'. YAML uses a list. Regex quantifiers such as
--name '~worker-[0-9]{1,3}$' remain intact. Group matches and direct patterns
use the same matching semantics; -s or select.status is an additional filter.
A pattern is at most 4096 characters. Regex syntax is checked with Python re;
matching uses regex VERSION0 with a 50 ms limit per pattern/value comparison.
Invalid, oversized or timed-out patterns fail explicitly, never selecting all
containers as a fallback. This is not a total cycle deadline. Globs retain
case-sensitive whole-value matching; regexes retain start-of-value matching.
An empty result is error 114, not a successful no-op. Container iteration order comes from Docker and is not promised to be sorted.
Global options¶
Options |
Default / constraints |
|---|---|
|
Configuration precedence above |
|
Client precedence above |
|
Selection above; status is one of |
|
|
|
|
|
|
|
300 seconds; integer 1..86400 |
|
|
|
5242880; integer at least 65536 |
|
5; integer 1..100 |
An empty audit path is invalid. Export/forwarding and authenticated journal reads require an explicit audit path (the environment variable also counts). Environment-derived configuration/log/runtime defaults are read when the CLI module is imported; set them before launching the process.
Rules and action aliases¶
--cmd and --cmd-if are aliases for the same repeatable option. A rule is an
unconditional action, CONDITION ? ACTION, or @condition_alias ? @command_alias;
inline and aliased sides can be mixed. A command alias expands to its ordered
action list; a condition alias expands to conditions combined with AND. Alias
entries do not recursively reference other aliases.
Docker actions are start, stop, remove, reload, restart, kill, pause,
unpause. Parenthesized text such as (sh -c "echo ready") is a Docker exec
command; use an explicit shell when shell syntax is needed. In a command alias,
an action can be a string or a single-key mapping whose options are args (list)
and kwargs (mapping), passed to the Docker SDK. Offline validation does not
guarantee that every SDK keyword is supported. Completed exec status is required;
detached or streaming execs cannot be reported as successful monitored actions.
Numeric comparisons use ==, !=, <, <=, >, >=, nonnegative numeric
literals and, where supported, byte units such as MiB. State membership uses
in (paused,running) or not in (paused, running). Spaces and tabs around commas are optional.
Resource-specific bounds/operators are described in the check guides. Conditions
for one directory group must be satisfied together by at least one path in that
group. Separate groups and ordinary conditions are combined with AND.
Rules requiring only status/PID/health run before metric-dependent rules, even
when their CLI order is interleaved. Within each phase, input order is preserved.
Metric rules only run when the container is running or paused. This two-phase
behavior remains when converting commands into scenarios. Chained numeric
comparisons follow Python operand order: 10 < cpu_percent < 90 means
10 < cpu_percent and cpu_percent < 90. Bounds can include supported byte units.
Subcommands and outputs¶
Command |
Options / behavior |
|---|---|
|
Repeatable |
|
Repeatable |
|
Repeatable |
|
Continuous collection; repeatable |
|
|
|
JSON array of |
|
One rendered scenario object as JSON; can contain command arguments; not a fully expanded default-option dump |
|
Run one exact scenario; optional |
|
|
|
|
|
|
|
Export filters plus required |
|
Simulation by default or |
stats --output json emits one JSON object per container, not a single array.
Each maps the container name to requested resource values. Memory, disk and I/O
values are human-readable unit strings where applicable. Text uses
NAME|RESOURCE:VALUE|.... monit text keeps raw units. Unavailable displayed
values may be null. Do not parse diagnostic logs as command output.
With no --rsc, stats and serve request mem_usage, mem_limit, mem_percent,
cpu_percent, io_read, io_write, net_tx, net_rx, status, pid, health.
Additional resources are oom_events, starts_recent, pids_current,
pids_limit, pids_percent, and filesystem resources such as disk_percent[data].
See filesystem, access and
runtime references for all resource meanings and prerequisites.
Rules emit JSON action decisions containing container_id, rule, command
and status. Current statuses include executed, dry-run, cooldown,
pending, restart-limit, maintenance. Nonmatching rules emit no decision.
Docker exec output is not passed through as a structured stdout result.
The first action failure aborts the remaining actions and containers.
check-config --output json returns {valid, errors, summary} on stdout.
Errors contain location and message; validation stops at the first error.
Summary counts clients, groups, commands, conditions, rules, plus
scenarios when present. It validates dormant aliases/groups/scenarios as well
as supplied rules. scenario list, show and run validate all configured scenarios and aliases. Their
configuration errors go to stderr and return 110.
These inspection commands do not connect to Docker or create agent state/log
files. maintenance and restart-reset also avoid Docker but mutate local state
and write audit events. A dry run collects live Docker data; cron/serve can create
a lock and audit simulated decisions while preserving durable policy state.
Policy and listener options¶
Option |
Modes |
Default / constraints |
|---|---|---|
|
|
Nonempty path; required in cron, or serve with rules/manual actions |
|
|
300 seconds; finite and nonnegative |
|
|
3; positive integer, attempts per container until rearm |
|
|
0; finite and nonnegative; positive value requires rules and |
|
|
Finite positive seconds; only with positive trigger delay; must exceed interval in serve |
|
|
IPv4 |
|
|
30 seconds; finite and at least 0.1 |
|
|
|
|
|
Off; requires rules; incompatible with manual HTTP actions |
|
|
Off; requires state, action token and exact HTTPS origin |
|
|
Require |
|
|
30 seconds; finite and at least 1 |
|
|
Off; requires |
|
|
Off; requires manual actions or an audit read token. Trust the authenticated proxy to supply the username. |
|
|
Off; requires explicit audit path and a distinct read secret |
|
|
Optional dedicated bearer secret for GET and HEAD on |
|
|
Optional dedicated bearer secret for GET and HEAD on |
|
|
Off; private notification ingestion secret |
Keep one persistent state path per Docker host/job. A busy state lock fails immediately with 117. See cron, trigger delay, restart limits and serve for policy and token details.
Scenario fields and overrides¶
Scenario mode defaults to cron. All modes allow mode, description,
select or all: true, client, client-from-env, event-window, audit-file,
audit-max-bytes, audit-files. Selection fields are name, id, image,
label, group, status, each a string or nonempty string list. Choose select
or all: true, exclusively. Group selection intersects direct patterns; status is applied in addition.
Mode |
Additional fields |
|---|---|
|
|
|
|
|
All cron fields plus |
resources and rules accept a string or nonempty string list. Booleans must be
YAML booleans, not strings. Integer fields accept integers or integer strings;
other numeric fields accept finite numbers or numeric strings, including template
results, then apply CLI bounds. Unknown or wrong-mode fields are rejected.
run/scenario reject global selectors and Docker-client overrides. Configuration,
log and runtime paths are inherited; global audit/event-window settings apply
unless the scenario defines them. CLI run --dry-run only enables simulation.
The configuration is rendered once and passed to the runner. Scenario names do
not identify cooldowns: changing the state path starts separate policy history.
Manual HTTP action options and exec-exit propagation are not scenario fields.
Since 0.0.77, access resources in stats/serve scenarios require the directory
group’s access identity during offline validation, just as access rules and
execution do. Disk/inode/mount-mode resources do not require it.
Exit codes¶
Code |
Meaning |
|---|---|
0 |
Successful command; can mean no rule matched or all actions were skipped |
2 |
Argument parsing/validation error, before command execution |
110 |
Configuration, alias, scenario or value error handled as such |
114 |
No container selected |
115 |
Required observation unavailable |
116 |
Action failure or unknown exec outcome. See exec wait limits |
117 |
Persistent state lock busy |
118 |
State read/write/validation failure |
119 |
Audit error, or handled OS/value errors in local administration commands |
140 |
Rule syntax error reaching the historical runtime CLI |
150 |
Unexpected exception reaching the historical runtime CLI |
170 |
Docker SDK connection/client error |
180 |
Docker API error during collection; action API failures normally become 116 |
255 |
Interrupt/SystemExit handled inside the runtime CLI; not a promise for every signal or every entry point |
Some monit --rsc invocations intentionally return data as the process status:
status: running 0, created 10, paused 20, restarting 30, removing 40, exited 50, dead 60.health: healthy 0, starting 10, unhealthy 20, none 30, unknown 115.One ordinary
*_percentresource: integer truncated and bounded to 0..100. Rawstats/rule measurements are not capped. Filesystem percentages return per-path output instead.
These early exits describe the first selected container, not an aggregate.
Use an exact container selector for a process-status check. --propagate-exit-code
in monit/cron returns a failed completed exec’s 1..255 status instead of 116;
it can overlap every other status family. Check command mode and diagnostics.
Decisions retained in 1.0¶
The five CLI/YAML choices were approved on 2026-09-27: shared strict validation, unknown-client rejection, group/direct intersection, literal selector commas, and Python-order chained comparisons. Their implementation is included in 0.0.80; see migration examples and limits.
Compatibility does not certify every deployment environment or workload. Local YAML remains the configuration model; the local CLI adds no login. Protected remote access retains its authentication.
Internal Python classes, diagnostic wording, implicit argparse abbreviations, Docker enumeration order and undocumented YAML behavior are not stable APIs.
Verification¶
test_cli_contract.py covers target selection, label values/image tags, regular
expression boundaries, group/direct intersection, import replacement, client precedence
and option placement. test_scenarios.py covers scenario overrides, offline
inspection, single rendering, state continuity and access-resource validation.
Existing test_check_config.py, test_monit_docker.py, test_cron.py,
test_trigger_delay.py and test_restart_limit.py cover diagnostics, exit-code
propagation and persistent policies. These tests support this inventory; they
do not complete every milestone in the 1.0 roadmap.