Driving RollDev from a Script
Everything RollDev does also works without a terminal: from a CI job, a deploy script, a build server that rebuilds environments overnight, or an AI assistant. This page lists the parts of the interface meant for that.
Don’t parse the human output. It carries ANSI colour and its layout can change between releases. The JSON output below is the stable interface.
Machine-Readable Output
Four commands accept --format json:
roll status --format json # every project on the host
roll env describe --format json # one project, its services and their state
roll registry list --format json # every available command, with descriptions
roll env doctor --format json # per-check diagnostics
The JSON contains no ANSI escapes and no credentials, and values are escaped, so a path with a quote or a non-ASCII character still parses.
status and describe share the fields name, type, dir, url, network and containers:
statusreturns{"running": true, "projects": [ … ], "services": [ … ]}.runningsays whether the global RollDev services are up,projectsholds one object per environment on the host, andserviceslists the global services such as traefik and dnsmasq.describereturns one project object with aservicesarray for that project’s containers.
Every service entry has at least name and status.
# services of this project that are not running
roll env describe --format json | jq -r '.services[] | select(.status != "running") | .name'
# every environment on the host
roll status --format json | jq -r '.projects[].name'
doctor returns an overall ok and a checks array with one entry per check. A check skipped with --ignore-services reports "ok": null. See Doctor.
registry list returns command, category, description, priority and source per command. priority is the search tier: project .roll/commands (1), ~/.roll/commands (2), ~/.roll/reclu (3), built-in (4). The lowest number wins, so a project command replaces a built-in with the same name.
Feature Detection
Which commands exist depends on the RollDev version, on installed command packs, and on the project’s own commands. Check before you call one:
if roll has-command dpull; then
roll dpull
fi
has-command prints nothing and exits 0 or 1. It resolves through the registry, so it also finds project and add-on commands.
Waiting for Services
roll env up returns once Compose has started the containers, before the services inside are ready. Add --wait:
roll env up --wait
roll db connect -e 'SELECT 1'
--wait uses the healthchecks for db, redis, elasticsearch, opensearch and rabbitmq. nginx and varnish have none, because Traefik stops routing to a container whose healthcheck is still starting or failing. The search engines are checked through /_cluster/health, because their containers can keep the port open while the cluster inside has died.
Containers created before the healthchecks existed have no health status, so --wait cannot wait for them. Recreate the environment once after upgrading: roll env down && roll env up.
Prompts Without a Terminal
A prompt takes its value from a flag, positional argument or environment variable first. Only with a terminal on stdin does it ask. Without one, it fails at once and names the flag to use:
ERROR: Cannot prompt for a password: no terminal attached.
ERROR: Supply it non-interactively with --encrypt=<password>.
| Prompt | Non-interactive form |
|---|---|
roll env-init name and type |
roll env-init <name> <type> |
roll env-init overwrite confirmation |
ROLL_ENV_INIT_FORCE=1 |
roll backup encryption password |
--encrypt=<password> |
roll restore decryption password |
--decrypt=<password> |
roll duplicate encryption password |
--encrypt=<password> |
roll copyfromcontainer file picker |
--cachegrind <file> or --traces <file> |
Exit Codes
| Code | Meaning |
|---|---|
0 |
Success. For doctor, every check passed. For has-command, the command exists. |
1 |
Failure. For doctor, at least one check failed. For has-command, no such command. |
--help exits 1 as well. That is long-standing behaviour, not a failure.
Running Many Environments on One Host
ROLL_PUBLISH_PORTS=0stops BrowserSync from publishing host ports that collide between environments.ELASTICSEARCH_JAVA_OPTSandOPENSEARCH_JAVA_OPTSset the search engine heap per project.
See Unattended Operation.
Example
#!/usr/bin/env bash
set -euo pipefail
roll env up --wait
if ! roll env doctor --format json > doctor.json; then
jq -r '.checks[] | select(.ok == false) | "\(.check): \(.detail)"' doctor.json >&2
exit 1
fi
roll env sh php-fpm 'bin/magento setup:upgrade > var/log/upgrade.log'
roll env exec php-fpm bin/magento ... > out.log writes out.log on the host. roll env sh runs the command through sh -c in the container, so redirects and pipes apply there.