Portal Community
  Exec into containers is a powerful operation. A command running inside a container has access to all container filesystems, environment variables, and network interfaces. Restrict the commands that can be executed via workflow configuration. Never interpolate user input into the Command field — this is equivalent to a remote code execution vulnerability.

When to Use

Configuration

Connection Fields

FieldTypeDefaultDescription
dockerHoststringunix:///var/run/docker.sockDocker socket path or TCP endpoint
connectionTypestringunixsocketunixsocket | tcp | tcptls
tlsCertPathstringTLS certificate directory. Required for tcptls. optional
timeoutSecondsint30Timeout for exec operation. Increase for long-running commands (e.g. migrations). optional

Operation Fields

FieldTypeRequiredDescription
resourcestringrequiredMust be container
operationstringrequiredMust be exec
ContainerIdstringrequiredContainer ID or name. Container must be running.
CommandstringrequiredJSON array of command and arguments: ["sh", "-c", "ls /app"]. Never use string concatenation with external input.
AttachStdinboolfalseAttach stdin to the exec process. optional
AttachStdoutbooltrueCapture stdout from the exec process. optional
AttachStderrbooltrueCapture stderr from the exec process. optional

Sample Configuration

{
  "resource": "container",
  "operation": "exec",
  "ContainerId": "api-service",
  "Command": "[\"sh\", \"-c\", \"node scripts/health-check.js\"]",
  "AttachStdout": true,
  "AttachStderr": true,
  "connection": {
    "dockerHost": "unix:///var/run/docker.sock",
    "connectionType": "unixsocket",
    "timeoutSeconds": 15
  }
}

Validation Errors

Error CodeTriggerResolution
MISSING_INPUTContainerId or Command is emptyBoth fields are required. Command must be a valid JSON array string.
NOT_FOUNDContainer does not existVerify the container name or ID.
CONFLICTContainer is not running (it is stopped or paused)Start the container first with container/start. Exec only works on running containers.
CONFIG_ERRORMalformed JSON in Command fieldValidate that the Command value is a proper JSON array: ["cmd", "arg1", "arg2"].
DOCKER_API_ERRORCommand executable not found inside containerVerify the command binary exists in the container's PATH.

Output

Success Port

FieldTypeDescription
exitCodeintExit code of the executed command. 0 = success, non-zero = failure.
stdoutstringStandard output from the command
stderrstringStandard error from the command
statusstringsuccess — note: this means the exec call completed, not that the command itself succeeded. Always check exitCode.
resourcestringcontainer
operationstringexec

Error Port

The error port fires for Docker API-level failures (container not found, daemon errors). A command that runs but exits with a non-zero code still fires the success port — check exitCode !== 0 with an If Condition node to handle command failures.

Sample Output

{
  "exitCode": 0,
  "stdout": "Health check passed\nDatabase connection: OK\nRedis connection: OK\nAll checks passed (3/3)",
  "stderr": "",
  "status": "success",
  "resource": "container",
  "operation": "exec"
}

Expression Reference

ExpressionReturns
{{ $output.exitCode }}Command exit code — 0 is success
{{ $output.exitCode === 0 }}Boolean — true if command succeeded
{{ $output.stdout }}Full standard output string
{{ $output.stderr }}Full standard error string
{{ $output.stderr.length > 0 }}Boolean — true if stderr has content
{{ $output.stdout.trim() }}Trimmed output for use in conditions or messages

Node Policies & GuardRails

PolicyDetail
Never interpolate user input into CommandGuardRail static analysis blocks any Command value that contains {{ $trigger.* }}, {{ $input.* }}, or other external input expressions. Commands must be fully static or built from validated workflow variables only.
Use pre-approved command listsOrganizations should maintain a whitelist of permitted exec commands. Arbitrary exec grants container-level root access. GuardRail exec policies can enforce prefix matching against an allowed command list.
Check exitCode, not just statusThe node success port fires even when the command exits with code 1 or higher. Always follow exec with an If Condition node checking exitCode === 0.
Increase timeout for migrationsDatabase migrations can take minutes. Set timeoutSeconds high enough to avoid premature cancellation.
No remote TCP without TLSUse tcptls for remote Docker hosts.

Examples

Example 1: Run database migrations before traffic cutover

{
  "resource": "container",
  "operation": "exec",
  "ContainerId": "api-service-blue",
  "Command": "[\"node\", \"scripts/migrate.js\", \"--env\", \"production\"]",
  "AttachStdout": true,
  "AttachStderr": true,
  "connection": { "timeoutSeconds": 120 }
}
// If Condition: exitCode === 0 → proceed to traffic switch
// Else: stop blue container, rollback deploy

Example 2: Application health check after start

{
  "resource": "container",
  "operation": "exec",
  "ContainerId": "api-service",
  "Command": "[\"sh\", \"-c\", \"wget -qO- http://localhost:8080/health || exit 1\"]",
  "AttachStdout": true,
  "AttachStderr": true
}
// exitCode 0 → container is healthy, proceed
// exitCode 1 → container started but application not ready, retry or alert

Example 3: Trigger cache flush in running application

{
  "resource": "container",
  "operation": "exec",
  "ContainerId": "cache-service",
  "Command": "[\"redis-cli\", \"FLUSHDB\"]",
  "AttachStdout": true,
  "AttachStderr": true
}
// stdout will contain "OK" on success
// If Condition: stdout.trim() === 'OK' → log success
// Else: alert operations team