Files
OpenShell/architecture/build.md

5.3 KiB

Build

This page records the stable build, CI, docs, and release architecture. It is not a command reference. Contributor-facing workflow details live in CONTRIBUTING.md, CI.md, and published docs.

Artifacts

OpenShell builds these main artifacts:

Artifact Source
Gateway binary crates/openshell-server
CLI package and Python SDK python/openshell plus Rust binaries where packaged
Gateway container image deploy/docker/Dockerfile.gateway
Supervisor container image deploy/docker/Dockerfile.supervisor
Helm chart deploy/helm/openshell
VM driver/runtime assets crates/openshell-driver-vm
Published docs site docs/ rendered by Fern config in fern/

Sandbox community images are built outside this repository.

Linux Runtime Environments

OpenShell uses different Linux libc environments for different host artifacts. The standalone openshell CLI is built as a static musl binary so it can run on a wide range of Linux distributions without depending on the host's glibc. Host runtime binaries that use the GNU/Linux runtime environment, including openshell-gateway and openshell-driver-vm, are GNU-linked and built with a glibc 2.31 floor.

Container Builds

The Docker image pipeline is a two-step flow: build the Rust binary natively for the target architecture, then assemble the container image from the prebuilt binary. The gateway image is built from deploy/docker/Dockerfile.gateway and the supervisor image from deploy/docker/Dockerfile.supervisor. Neither Dockerfile compiles Rust — both copy a staged binary out of deploy/docker/.build/prebuilt-binaries/<arch>/ into the final image.

Binary staging is driven by tasks/scripts/stage-prebuilt-binaries.sh. Gateway binaries use cargo zigbuild with GNU targets pinned to glibc 2.31, including native-architecture builds, so the gateway image, standalone tarballs, and Linux packages share the same host portability floor. Supervisor binaries remain static musl. Local Docker image tasks infer the target architecture from DOCKER_PLATFORM when set, otherwise from the container engine host metadata with the kernel architecture as the fallback. CI invokes the same staging step via the rust-native-build.yml workflow (per-architecture, per-component) and uploads the result as an artifact that the image build job downloads back into the staging directory before running Buildx.

Runtime layout:

  • Gateway: gcr.io/distroless/cc-debian13:nonroot base, GNU-linked binary at /usr/local/bin/openshell-gateway, runs as UID/GID 1000:1000. Linux GNU gateway and VM driver binaries must not reference GLIBC_* symbols newer than GLIBC_2.31; release workflows verify this before publishing artifacts.
  • Supervisor: scratch base, static musl binary at /openshell-sandbox. Static linkage is required because the image is mounted/extracted into sandbox environments (Docker extraction, Podman image volumes, Kubernetes init-container copy-self) and cannot rely on a dynamic loader.

Gateway image builds bake the corresponding supervisor image tag into the gateway binary so Docker sandboxes do not depend on :latest by default. Package formulas also pin Docker supervisor extraction to the matching release image tag so standalone gateway binaries do not infer image tags from package versions. The Homebrew service keeps gateway TLS under the Homebrew state directory but mirrors Docker sandbox client TLS into $HOME/.local/state/openshell/homebrew/tls at service start, because Docker Desktop bind mounts must use paths visible to the macOS user's shared home directory.

Local image work should use mise tasks rather than direct Docker commands so the same staging and tagging assumptions are used locally and in CI.

CI and E2E

Required checks run on GitHub Actions. Workflows that use NVIDIA self-hosted runners trigger from copy-pr-bot mirror branches, so trusted PRs are mirrored into pull-request/<N> branches before those workflows run.

The high-level CI model:

  1. PR-context gate jobs publish required statuses for the PR head commit.
  2. Standard branch checks run from trusted mirror branches.
  3. Label-gated E2E, GPU, and Kubernetes checks run from trusted mirror branches.
  4. Gate jobs verify that the mirror branch matches the PR head and that the expected non-gate workflow actually ran.
  5. Release workflows rebuild and publish binaries, wheels, images, and docs.

See CI.md for the contributor workflow and labels.

Docs Site

Published docs live in docs/. Navigation lives in docs/index.yml. Fern site configuration, components, theme assets, and publish settings live in fern/.

Use mise run docs for strict validation and mise run docs:serve for local preview. PR previews are produced by .github/workflows/branch-docs.yml when Fern credentials are available. Production docs publish from the release tag workflow.

Validation Expectations

  • Run mise run pre-commit before committing.
  • Run mise run test after code changes.
  • Run mise run e2e for sandbox, policy, driver, or deployment changes when the affected runtime can be exercised.
  • Run mise run ci before opening a PR when practical.
  • Run mise run docs when docs/ or fern/ changes.

Architecture-only changes should still check links and references because this directory is used by agents during implementation and review.