5.8 KiB
Container Images
OpenShell produces two container images, both published for linux/amd64 and linux/arm64.
Gateway (openshell/gateway)
The gateway runs the control plane API server. It is deployed as a StatefulSet inside the cluster container via a bundled Helm chart.
- Docker target:
gatewayindeploy/docker/Dockerfile.images - Registry:
ghcr.io/nvidia/openshell/gateway:latest - Pulled when: Cluster startup (the Helm chart triggers the pull)
- Entrypoint:
openshell-gateway --port 8080(gRPC + HTTP, mTLS)
Cluster (openshell/cluster)
The cluster image is a single-container Kubernetes distribution that bundles the Helm charts, Kubernetes manifests, and the openshell-sandbox supervisor binary needed to bootstrap the control plane.
- Docker target:
clusterindeploy/docker/Dockerfile.images - Registry:
ghcr.io/nvidia/openshell/cluster:latest - Pulled when:
openshell gateway start
The supervisor binary (openshell-sandbox) is built before the image build, staged under deploy/docker/.build/prebuilt-binaries/<arch>/, and copied into the cluster image at /opt/openshell/bin/openshell-sandbox. It is exposed to sandbox pods at runtime via a read-only hostPath volume mount — it is not baked into sandbox images.
Image Build Pipeline
deploy/docker/Dockerfile.images no longer compiles Rust. CI calls .github/workflows/shadow-rust-native-build.yml through workflow_call to build openshell-gateway or openshell-sandbox natively on the target architecture. .github/workflows/docker-build.yml downloads the resulting artifact, stages it at deploy/docker/.build/prebuilt-binaries/<arch>/, builds the per-arch image with the local Buildx driver, and merges multi-arch pushes with docker buildx imagetools create. Callers normally publish the GitHub SHA tag, but shadow workflows can pass image-tag to publish isolated temporary tags for validation.
Local Docker builds use tasks/scripts/stage-prebuilt-binaries.sh through tasks/scripts/docker-build-image.sh before invoking Docker, so clean checkouts do not need to create the staging directory manually.
Standalone Gateway Binary
OpenShell also publishes a standalone openshell-gateway binary as a GitHub release asset.
- Source crate:
crates/openshell-server - Artifact name:
openshell-gateway-<target>.tar.gz - Targets:
x86_64-unknown-linux-gnu,aarch64-unknown-linux-gnu,aarch64-apple-darwin - Release workflows:
.github/workflows/release-dev.yml,.github/workflows/release-tag.yml - Installer: None yet. The binary is a manual-download asset.
Both the standalone artifact and the deployed container image use the openshell-gateway binary.
Python Wheels
OpenShell also publishes Python wheels for linux/amd64, linux/arm64, and macOS ARM64.
- Linux wheels are built natively on matching Linux runners via
build:python:wheel:linux:amd64andbuild:python:wheel:linux:arm64intasks/python.toml. - There is no local Linux multiarch wheel build task. Release workflows own the per-arch Linux wheel production.
- The macOS ARM64 wheel is cross-compiled with
deploy/docker/Dockerfile.python-wheels-macosviabuild:python:wheel:macos. - Release workflows mirror the CLI layout: a Linux matrix job for amd64/arm64, a separate macOS job, and release jobs that download the per-platform wheel artifacts directly before publishing.
Sandbox Images
Sandbox images are not built in this repository. They are maintained in the openshell-community repository and pulled from ghcr.io/nvidia/openshell-community/sandboxes/ at runtime.
The default sandbox image is ghcr.io/nvidia/openshell-community/sandboxes/base:latest. To use a named community sandbox:
openshell sandbox create --from <name>
This pulls ghcr.io/nvidia/openshell-community/sandboxes/<name>:latest.
Local Development
mise run cluster is the primary development command. It bootstraps a cluster if one doesn't exist, then performs incremental deploys for subsequent runs.
The incremental deploy (cluster-deploy-fast.sh) fingerprints local Git changes and only rebuilds components whose files have changed:
| Changed files | Rebuild triggered |
|---|---|
| Cargo manifests, proto definitions, prebuilt staging script | Gateway + supervisor |
crates/openshell-server/*, crates/openshell-ocsf/*, deploy/docker/Dockerfile.images |
Gateway |
crates/openshell-sandbox/*, crates/openshell-policy/* |
Supervisor |
deploy/helm/openshell/* |
Helm upgrade |
When no local changes are detected, the command is a no-op.
Gateway updates are pushed to a local registry and the StatefulSet is restarted. Supervisor updates are copied directly into the running cluster container via docker cp — new sandbox pods pick up the updated binary immediately through the hostPath mount, with no image rebuild or cluster restart required.
Fingerprints are stored in .cache/cluster-deploy-fast.state. You can also target specific components explicitly:
mise run cluster -- gateway # rebuild gateway only
mise run cluster -- supervisor # rebuild supervisor only
mise run cluster -- chart # helm upgrade only
mise run cluster -- all # rebuild everything
To validate incremental routing and BuildKit cache reuse locally, run:
mise run cluster:test:fast-deploy-cache
The harness runs isolated scenarios in temporary git worktrees, keeps its own state and cache under .cache/cluster-deploy-fast-test/, and writes a Markdown summary with:
- auto-detection checks for gateway-only, supervisor-only, shared, Helm-only, unrelated, and explicit-target changes
- cold vs warm rebuild comparisons for gateway and supervisor code changes
- container-ID invalidation coverage to verify gateway + Helm are retriggered when the cluster container changes