> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tokenfactory.nebius.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Prepare and reuse environments

> Create a reusable filesystem image from setup commands, OCI import, or the supported CLI Dockerfile workflow.

Move stable setup out of repeated work. Record the immutable UUID produced by preparation and start later operations from that UUID.

## Choose a preparation path

| Input | Public path | Result |
| - | - | - |
| Existing Sandboxes image | `images.use(UUID, strict=True)` | Verified image reference; no compute |
| OCI registry image | `images.import_from()` or `images.oci()` | Imported filesystem image |
| Setup command | `image.run(..., disposable=False)` | Result image containing filesystem changes |
| Dockerfile subset | CLI 0.9.4 `contree build` | Cached checkpoint sequence and final tag |

OCI import captures the filesystem root. Do not rely on OCI `CMD`, `ENTRYPOINT`, ports, health checks, or a service lifetime as the command for a later operation.

## Python preparation

Complete [Set up access](/sandboxes/start/set-up-access). In a fresh project, run `uv init --python 3.12` and `uv add "contree-sdk==0.3.6"`. The fragments below run inside an async `main()`; [Prepare once, reuse safely](/sandboxes/cookbook/prepare-once-reuse-safely) contains the complete entry point.

With `contree-sdk==0.3.6`, `run()` prepares an awaitable request and execution begins when it is awaited:

```python theme={null}
from contree_sdk import Contree

client = Contree()
base = await client.images.oci("docker.io/library/alpine:3.19")
prepared = await base.run(
    shell="mkdir -p /opt/example && printf 'version=1\\n' > /opt/example/config.ini",
    disposable=False,
    timeout=60,
)
if prepared.exit_code != 0 or prepared.uuid is None:
    raise RuntimeError("Preparation failed or returned no saved image")
checkpoint_uuid = prepared.uuid
```

A later read starts new compute:

```python theme={null}
checkpoint = await client.images.use(checkpoint_uuid, strict=True)
verification = await checkpoint.run(
    shell="cat /opt/example/config.ini",
    disposable=True,
    timeout=30,
)
if verification.exit_code != 0:
    raise RuntimeError(f"Configuration read failed: {verification.stderr}")
if verification.stdout != "version=1\n":
    raise RuntimeError("The saved configuration has an unexpected value")
if verification.uuid is not None:
    raise RuntimeError("A disposable read unexpectedly returned a saved image")

print(verification.stdout, end="")
```

Expected output:

```text theme={null}
version=1
```

Filesystem state survives only through a retained image. Processes, memory, services, and network connections do not.

## Dockerfile and refresh rules

CLI 0.9.4 supports `FROM`, `RUN`, `COPY`/`ADD`, `WORKDIR`, `ENV`, `ARG`, and `USER`. Multi-stage `AS` is parsed but not executed. Each `RUN` is a Sandboxes operation; the client caches compatible layers. Use `--no-cache` for a deliberate full rebuild.

Pin base images and dependencies, record the final UUID with the source revision, run a disposable smoke test, then move a shared tag. Keep registry credentials and build secrets outside uploaded files, retained environment values, and command output.

See [Build and refresh a reusable custom environment](/sandboxes/cookbook/build-reusable-custom-environment) and [Update images and clients](/sandboxes/operate/update-images-and-clients).
