Predicate are used to encapsulate build logic. Predicates in Modus belong to one of the three kinds: image predicates, layer predicates and logic predicates. Image predicates create new images, e.g. the predicate from, as well as any predicates that adds further layers upon a from. Layer predicates adds new layers on tops of an image, and can not itself be built, e.g. run or copy. Logic predicates does neither, can be used anywhere, but can not be built on its own. The kind of a predicate determines where it can be used. For example, a rule body can not contain more than one image predicates, nor can layer predicates appear before image predicates. The kind of a user-defined predicate is inferred automatically, while the kind of a builtin predicate is pre-defined.

Builtin predicates have Prolog-like signatures that specify which parameters have to be initialised:

predicate(?Variable1, +Variable2, -Variable3)


  • ? means: This variable can be either instantiated or not. Both ways are possible.
  • + means: This variable is an input to the predicate. As such it must be instantiated.
  • - means: This variable is an output to the predicate. It is usually non-instantiated, but may be if you want to check for a specific "return value".

For example, run has the signature run(+cmdline), which means that the argument has to be initialised.

fromImageRefer to existing local/registry image by its name
runLayerExecute shell command
copyLayerCopy local file/directory
number_eqLogic= for numbers
number_gtLogic> for numbers
number_ltLogic< for numbers
number_geqLogic>= for numbers
number_leqLogic<= for numbers
string_concatLogicConcatenate strings
string_lengthLogicCompute string length
semver_exactLogicEquality with compatibility check for SemVer versions
semver_gtLogic> for SemVer versions
semver_ltLogic< for SemVer versions
semver_geqLogic>= for SemVer versions
semver_leqLogic<= for SemVer versions