# okstra container — CLI Reference

> `okstra container` is a nonlinear tool that launches code from a verified task as a local docker compose group. Because it is a separate entry point from the phase flags in `okstra.sh`, it is documented here rather than in [cli.md](cli.md). See [project-structure-overview](project-structure-overview.md) §4.3 for the module location.

---

## Overview

- **What it is:** Deploys (`up`) the integrated code for a specific task to a task-specific docker compose container group and manages the lifecycle through `status`/`down`.
- **Orchestration only (does not generate files):** **Reuses** the target project's existing `docker-compose.yml`. It does not generate configuration files; if `docker-compose.yml` is missing, it reports what is missing and stops (the same applies if only a `Dockerfile` exists).
- **Nonlinear:** This is not a phase in `PHASE_SEQUENCE`. Any task key can be launched regardless of whether it has passed verification.
- **Single entry point:** The `/okstra-container-build` skill, `bin okstra container`, and Python `okstra_ctl.container` all converge on [`scripts/okstra_ctl/container.py`](../scripts/okstra_ctl/container.py) and its `provision_container_group`.
- **Source of truth (SSOT) for container existence:** Docker labels.

## Prerequisites

- `docker` / `docker compose` must be installed and operational. `up` fails when they are not installed, but `okstra doctor` emits only `[WARN]` and retains exit code 0 (container functionality is optional).
- The code for the target task key must be integrated into the task-key worktree HEAD. If there are unintegrated stages, `up` merges them (preserving the stage trees) before continuing; if a conflict occurs, it reports the conflicting files and stops.
- `docker-compose.yml` must exist at the worktree root.

## Command format

```
okstra container <up|status|down> --project-root <PATH> --task-key <KEY> [--text] [options]
```

| sub-command | Behavior | Additional options |
|---|---|---|
| `up` | Verify stage integration → validate `docker-compose.yml` → compose env override → `docker compose -p <project> up -d` → poll health checks | — |
| `status` | Show the live container group status by querying Docker labels | — |
| `down` | Tear down the container group | `--all` |

## Arguments

### `--project-root` (required)
Absolute path to the target project root. Required for every sub-command.

### `--task-key` (effectively required)
Identifier of the task to deploy, in the form `<project-id>:<task-group>:<task-id>`. The default is an empty string, but actual operations require a valid task key.

`--text` emits command-specific fixed labels for model-facing skills. Without it, the command preserves the full machine JSON bytes and exit codes.

### `--all` (`down` only)
Tear down **all** task container groups discovered under the current project root's `.okstra/` scope. Without `--all`, `down` tears down exactly the group named by `--task-key`.

## How `up` works

1. **Resolve source tree** — Use the task-key worktree HEAD. Merge unintegrated stages (`teardown=False`, preserving stage worktrees). Stop and identify conflicting files if a conflict occurs (retries are safe because the already-merged operation is idempotent).
2. **Validate configuration file** — Check for `docker-compose.yml` at the worktree root. If it is missing, stop after identifying the missing filename (do not generate it).
3. **Scan bind mounts** — If the normalized output of `docker compose config` contains a host path outside the worktree (`../` or an absolute path), **warn and continue** (do not stop; warn that the container may write files to the host).
4. **Compose env override** — In the okstra-owned worktree, layer task overrides over `.env`, write the result to `env.override`, and pass the files in the order `--env-file <worktree .env> --env-file <env.override>` (the latter takes precedence).
5. **Deploy** — Run `docker compose -p <project-name> ... up -d`. Obtain the service list from `docker compose config --services` (the canonical source).
6. **Poll health checks** — Use `docker compose ps` to verify that each service has started. Success means reaching healthy for services with a health check, or `running` for services without one.

### Fixed defaults (not currently exposed as CLI flags)

| Value | Default | Meaning |
|---|---|---|
| healthcheck timeout | 120 seconds | Stop and report services that failed to start after this limit |
| healthcheck interval | 3 seconds | Polling interval for `docker compose ps` |

> These values exist as named arguments to `provision_container_group`, but because they are not exposed as CLI flags, they currently operate as fixed values.

## Labels and artifacts

Three labels are attached to deployed containers. The label queries used by `status`/`down` use them to locate the group.

| Label | Value |
|---|---|
| `okstra.task-key` | `<project-id>:<task-group>:<task-id>` |
| `okstra.project-name` | compose project name `okstra-<proj>-<group>-<task>` |
| `okstra.run-trace` | run-trace slug (`okstra-container-<slug>`) |

All okstra artifacts are stored under `<project-root>/.okstra/tasks/<group>/<task-id>/container/` (the original project files remain unchanged):

```
container/
├── env.override            # per-task variables layered over the project .env
└── deploy-state.json       # compose project name, running containers, labels
```

## Exit behavior/output

Each sub-command returns exit code 0 on success. `--text` writes its command-specific fixed labels for model callers; the default writes the full machine JSON contract. Validation failures (missing configuration files, merge conflicts, health check timeouts, and so on) terminate abnormally with a `PrepareError` that identifies what went wrong.

## Usage examples

```bash
# Deploy
okstra container up --project-root /path/to/proj --task-key proj:auth:login-fix --text

# Status
okstra container status --project-root /path/to/proj --task-key proj:auth:login-fix

# Tear down the group
okstra container down --project-root /path/to/proj --task-key proj:auth:login-fix

# Remove every container group for this project
okstra container down --project-root /path/to/proj --all
```
