# Run container

Run an admitted container image to completion over the step's records.

## When to use it

Use an available, admitted workload for processing that needs its own execution environment. The workload receives the step’s input and returns records. Only offered workload images are eligible; typing an arbitrary image name does not make it available.

## Add and configure

1. Add **Run container** from the workflow step picker.
2. Give the step a recognisable name and connect its required inputs.
3. Set the options below. Nested names identify fields within an object or a list item.
4. Validate the recipe, inspect the test result, then run it on the intended data.

The step identifier used in the editor’s code view is `container_run`.

## Settings

| Setting | Accepted value | Required | Default | What it controls |
| --- | --- | --- | --- | --- |
| Args (`args`) | list of string; maximum items 1024 | No | Not specified | Arguments to the command. |
| Command (`command`) | list of string; maximum items 256 | No | Not specified | Overrides the image's entrypoint. |
| Egress Class (`egress_class`) | string; minimum characters 1 | No | "none" | Network egress: `none` (no network) unless the operator admits another class (e.g. `internet`). |
| Env (`env`) | object of string | No | Not specified | Environment (at most 64 entries). |
| Idempotency Key Template (`idempotency_key_template`) | string; minimum characters 1 | No | "${tenant_id}:${run_id}:${step_id}" | The workload's `Idempotency-Key` (variables `${tenant_id}`, `${run_id}`, `${step_id}`): a retry or a replay of the step with the same key resumes the same workload instead of starting another. |
| Image (`image`) | string; pattern `^[^\s@]+@sha256:[0-9a-f]{64}$` | Yes | Not specified | The image, digest-pinned (`<repo>@sha256:<hex>`) and admitted by the operator. |
| limits (`limits`) | object or null | No | null | Resource limits. |
| Cpu (`limits.cpu`) | number; minimum 0.1; maximum 4.0 or null | No | null | CPUs. |
| Memory Mb (`limits.memory_mb`) | integer; minimum 64; maximum 4096 or null | No | null | Memory, MiB. |
| Pids (`limits.pids`) | integer; minimum 10; maximum 1000 or null | No | null | Max processes. |
| Max Output Bytes (`max_output_bytes`) | integer; minimum 1; maximum 268435456 | No | 16777216 | The largest `/outputs/records.jsonl` read back. |
| Queue Wait Seconds (`queue_wait_seconds`) | integer; minimum 0; maximum 86400 | No | 600 | How long the workload may wait for a start slot (the tenant's quota, Strive's fair queue) on top of `timeout_seconds`; past both it is cancelled and the step fails with `timeout`. |
| Secrets (`secrets`) | list of object; maximum items 16 | No | Not specified | Connection secrets mounted read-only at `/run/secrets/<name>` (at most 16, distinct names). Strive resolves each when the container starts; the step's config and the workload's record hold the reference and name only. The container must not print the value or write it to /outputs: its log tail and output files become the step's records. A dry run refuses. |
| Connection Id (`secrets[].connection_id`) | string; pattern `^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$` | Yes | Not specified | The connection (its id) whose secret material is mounted. |
| Key (`secrets[].key`) | string; pattern `^[A-Za-z0-9_.-]{1,128}$` or null | No | null | One field of the secret material (else all of it, as compact JSON). |
| Name (`secrets[].name`) | string; pattern `^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$` | Yes | Not specified | The file under `/run/secrets`: lower-case letters, digits and `-` (a DNS label, at most 63 characters). |
| Timeout Seconds (`timeout_seconds`) | integer; minimum 10; maximum 86400 | No | 600 | The container's own deadline (10 s to 24 h). |

## Inputs and outputs

| Direction | Port | Content | Required | Multiple records |
| --- | --- | --- | --- | --- |
| Inputs | `in` | records | Yes | Yes |
| Outputs | `out` | records | Yes | Yes |

## Effects, testing, and recovery

Can write or act on an external destination.

The declared preview behaviour is to skip this step. Configuration can affect preview behaviour; HTTP GET is a notable exception. Read [dry runs](/docs/workflows/dry-runs) before using a preview with live connections.

Duplicate prevention uses the configured or operation-bound key; an external receiver must recognise it. The step declares safe replay for its supported recovery path.

## Example: Uppercase every record with a shell pipeline

Step settings:

```json
{
  "args": [
    "tr a-z A-Z < /inputs/records.jsonl > /outputs/records.jsonl"
  ],
  "command": [
    "sh",
    "-c"
  ],
  "image": "busybox@sha256:9db7b59979c38555a39def84a31fb98b5296952f9e3afd4f6f11f05b07adfab0",
  "timeout_seconds": 60
}
```

## Check the result

Inspect the selected run’s status, counts, errors, and output records. An empty collection can be a valid result, and a completed step can contain per-record failures where the step defines that behaviour. Check the next step’s expected record shape before publishing or delivering the result.
