# ociman - OCI Manager
A Rust library providing a unified API for OCI container runtimes (Docker, Podman).
> **Status**: Pre-1.0 - exists to serve [mbj/mrs](https://github.com/mbj/mrs) monorepo, expect breaking changes without notice.
## Goals
- **Unified API**: Single interface for OCI-compliant container runtimes
- **Auto-detection**: Automatically detects available container runtime
- **Environment override**: Control backend selection via `OCIMAN_BACKEND` environment variable
- **Container lifecycle management**: Run, execute commands, inspect, and manage containers
- **Image building**: Build images from Dockerfiles or inline instructions
- **Content-based hashing**: Automatic tag generation based on SHA256 of build context/instructions for deterministic builds
## Executing Commands in Containers
Use `container.exec()` to run commands inside a running container:
```rust,ignore
// Simple command execution
container.exec("echo")
.argument("hello")
.status()?;
// Capture stdout
let output = container.exec("cat")
.argument("/etc/os-release")
.build()
.capture_stdout()
.string()?;
// With environment variables and stdin
let result = container.exec("psql")
.argument("--dbname=mydb")
.environment_variable(PG_PASSWORD, "secret")
.stdin(b"SELECT 1;")
.build()
.capture_stdout()
.bytes()?;
```
The `ExecCommand` builder focuses on container exec configuration. For stream capture,
use `.build()` to get a `cmd_proc::Command`, then use its stream methods.
## Content-Based Image Hashing
ociman supports automatic tag generation based on content hashing (SHA256). This ensures deterministic builds where the same content always produces the same image tag.
Benefits:
- **Deterministic**: Same content always produces the same tag
- **Automatic cache invalidation**: Content changes automatically produce a new tag
- **No manual tag management**: Hash is computed automatically
- **Reproducibility**: Easy to verify if an image matches its source
**Important**: Content-based hashing only captures the Dockerfile and build context, not the base images. Using unspecific tags like `FROM alpine:latest` reduces reproducibility since `latest` can point to different images over time. For fully reproducible builds, use specific base image digests:
```dockerfile
# Less reproducible - tag can change
FROM alpine:latest
# More reproducible - specific version tag
FROM alpine:3.19
# Most reproducible - pinned to specific digest
FROM alpine@sha256:6457d53fb065d6f250e1504b9bc42d5b6c65941d57532c072d929dd0628977d0
```