Portal Community

When to Use

  Never put secrets in Env strings directly. Use {{ $credentials.name }} expressions to inject values from the BizFirst Credentials Manager, or mount secret files as volumes. Hard-coded passwords in Env fields will appear in container inspect output and Docker daemon logs.

Configuration

Connection Fields

FieldTypeDefaultDescription
dockerHoststringunix:///var/run/docker.sockDocker socket path or TCP endpoint
connectionTypestringunixsocketunixsocket | tcp | tcptls
tlsCertPathstringTLS certificate directory. Required for tcptls. optional
timeoutSecondsint30Operation timeout in seconds. optional

Operation Fields

FieldTypeRequiredDescription
resourcestringrequiredMust be container
operationstringrequiredMust be create
ImagestringrequiredImage name and optional tag (e.g. myapp:v2.1.0, nginx:latest)
NamestringoptionalContainer name. Strongly recommended for workflow readability and idempotency checks.
CommandstringoptionalOverride entrypoint command. JSON array string: ["node", "worker.js", "--mode", "batch"]
EnvstringoptionalJSON array of KEY=VALUE strings: ["NODE_ENV=production", "PORT=8080"]
PortBindingsstringoptionalJSON port mapping object. See format below.
VolumesstringoptionalJSON volume mount specification. See format below.

PortBindings Format

Map container ports to host ports. The key is {containerPort}/{protocol} and the value is an array of host binding objects:

{
  "8080/tcp": [{ "HostIp": "", "HostPort": "3000" }],
  "9229/tcp": [{ "HostIp": "127.0.0.1", "HostPort": "9229" }]
}

Volumes Format

Bind mounts and named volume mounts:

{
  "/app/data": {},
  "/app/config": {}
}

Sample Configuration

{
  "resource": "container",
  "operation": "create",
  "Image": "myapp:v2.2.0",
  "Name": "api-service-blue",
  "Env": [
    "NODE_ENV=production",
    "PORT=8080",
    "DB_URL={{ $credentials.dbUrl }}",
    "API_KEY={{ $credentials.apiKey }}"
  ],
  "PortBindings": "{\"8080/tcp\": [{\"HostIp\": \"\", \"HostPort\": \"3001\"}]}",
  "Volumes": "{\"/app/data\": {}, \"/app/logs\": {}}",
  "connection": {
    "dockerHost": "unix:///var/run/docker.sock",
    "connectionType": "unixsocket"
  }
}

Validation Errors

Error CodeTriggerResolution
MISSING_INPUTImage field is emptyProvide a valid image name. Run image/list to enumerate available images.
NOT_FOUNDImage does not exist locallyRun image/pull before container/create to ensure the image is available.
CONFLICTContainer name already in useRemove the existing container with container/remove first, or use a unique name.
CONFIG_ERRORMalformed JSON in PortBindings or EnvValidate JSON syntax. Use a Function node to build the JSON string programmatically.
DOCKER_API_ERRORDocker daemon error during creation (e.g. invalid port)Check the error message for specifics — common causes: port already in use, invalid volume path.

Output

Success Port

FieldTypeDescription
containerIdstringFull 64-character ID of the newly created container
containerNamestringName assigned to the container (with leading /)
warningsstring[]Non-fatal warnings from Docker daemon (e.g. deprecated options)
statusstringsuccess
resourcestringcontainer
operationstringcreate

Error Port

On failure, the error port receives errorCode, message, resource, and operation. Handle CONFLICT separately if your workflow is idempotent — the container may already exist from a previous run.

Sample Output

{
  "containerId": "a1b2c3d4e5f67890abcdef1234567890abcdef1234567890abcdef1234567890",
  "containerName": "/api-service-blue",
  "warnings": [],
  "status": "success",
  "resource": "container",
  "operation": "create"
}

Expression Reference

ExpressionReturns
{{ $output.containerId }}Full ID of the created container
{{ $output.containerId.substring(0, 12) }}Short container ID (12 chars) for display
{{ $output.containerName }}Container name string (e.g. /api-service-blue)
{{ $output.warnings.length }}Number of creation warnings (0 = clean)
{{ $output.warnings.join(', ') }}Concatenated warning messages for logging

Node Policies & GuardRails

PolicyDetail
No secrets in Env stringsGuardRail static analysis flags any Env value that is not a {{ $credentials.* }} expression and contains patterns matching API keys, passwords, or tokens.
Always use named containersWorkflows that use container/create without a Name field are flagged in code review. Names enable idempotency checks and make cleanup workflows reliable.
Pull image before createIf the image is not local, the Docker daemon will attempt a pull. In production workflows, explicitly use image/pull beforehand for controlled versioning.
No remote TCP without TLSUse tcptls for remote Docker hosts. Plain tcp is blocked in production GuardRail profiles.
Handle CONFLICT on error portRe-running a workflow without cleanup will cause a name conflict. Add a CONFLICT handler that removes the old container or generates a unique name.

Examples

Example 1: Blue-green deployment — create blue container

{
  "resource": "container",
  "operation": "create",
  "Image": "myapp:{{ $trigger.newVersion }}",
  "Name": "api-service-blue-{{ $trigger.deployId }}",
  "Env": [
    "NODE_ENV=production",
    "PORT=8080",
    "DB_URL={{ $credentials.dbUrl }}"
  ],
  "PortBindings": "{\"8080/tcp\": [{\"HostIp\": \"\", \"HostPort\": \"3001\"}]}"
}

Example 2: Ephemeral batch job container

{
  "resource": "container",
  "operation": "create",
  "Image": "batch-processor:stable",
  "Name": "batch-job-{{ $now | date('YYYYMMDD-HHmmss') }}",
  "Command": "[\"python\", \"run_batch.py\", \"--date\", \"{{ $trigger.batchDate }}\"]",
  "Env": [
    "S3_BUCKET={{ $vars.outputBucket }}",
    "AWS_ACCESS_KEY_ID={{ $credentials.awsKeyId }}",
    "AWS_SECRET_ACCESS_KEY={{ $credentials.awsSecretKey }}"
  ],
  "Volumes": "{\"/app/output\": {}}"
}

Example 3: Tenant database provisioning

{
  "resource": "container",
  "operation": "create",
  "Image": "postgres:15-alpine",
  "Name": "db-tenant-{{ $trigger.tenantId }}",
  "Env": [
    "POSTGRES_DB={{ $trigger.tenantId }}",
    "POSTGRES_USER=app",
    "POSTGRES_PASSWORD={{ $credentials.tenantDbPassword }}"
  ],
  "PortBindings": "{}",
  "Volumes": "{\"/var/lib/postgresql/data\": {}}"
}