# syntax=docker/dockerfile:1.4 # SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 # Shared OpenShell image build graph. # # Targets: # gateway Final gateway image # supervisor Final supervisor image (Ubuntu base, supervisor binary) # # Rust binaries are built natively before the image build and staged at: # deploy/docker/.build/prebuilt-binaries//openshell-{gateway,sandbox} # # For local dev (Skaffold), pass --build-arg BUILD_FROM_SOURCE=1 to compile # binaries inside Docker instead. BuildKit only executes the selected binary # staging stage, so missing prebuilt files do not cause a build failure. # Controls binary source: 0 = prebuilt (release), 1 = compile in Docker (local dev). # Must be declared here (global scope) so it can be used in FROM instructions below. ARG BUILD_FROM_SOURCE=0 # --------------------------------------------------------------------------- # Optional in-Docker Rust build (BUILD_FROM_SOURCE=1, local dev only) # --------------------------------------------------------------------------- FROM rust:1.95.0-slim-bookworm AS rust-builder RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential \ cmake \ pkg-config \ libssl-dev \ ca-certificates \ && rm -rf /var/lib/apt/lists/* WORKDIR /build COPY Cargo.toml Cargo.lock ./ COPY crates/ crates/ COPY proto/ proto/ COPY providers/ providers/ RUN --mount=type=cache,target=/usr/local/cargo/registry \ --mount=type=cache,target=/build/target \ cargo build --release \ --features "openshell-core/dev-settings" \ --bin openshell-gateway \ --bin openshell-sandbox \ && mkdir -p /build/out \ && install -m 0755 target/release/openshell-gateway /build/out/openshell-gateway \ && install -m 0755 target/release/openshell-sandbox /build/out/openshell-sandbox # --------------------------------------------------------------------------- # Per-arch binary stages # --------------------------------------------------------------------------- # Prebuilt path (release default, BUILD_FROM_SOURCE=0) FROM scratch AS gateway-binary-0 ARG TARGETARCH # --chmod=755 preserves the executable bit through actions/upload-artifact + # download-artifact, which strip exec perms during the roundtrip. COPY --chmod=755 deploy/docker/.build/prebuilt-binaries/${TARGETARCH}/openshell-gateway /build/out/openshell-gateway # Source-built path (local dev, BUILD_FROM_SOURCE=1) FROM rust-builder AS gateway-binary-1 FROM gateway-binary-${BUILD_FROM_SOURCE} AS gateway-binary # Prebuilt path (release default, BUILD_FROM_SOURCE=0) FROM scratch AS supervisor-binary-0 ARG TARGETARCH # --chmod=755 preserves the executable bit through actions/upload-artifact + # download-artifact, which strip exec perms during the roundtrip. COPY --chmod=755 deploy/docker/.build/prebuilt-binaries/${TARGETARCH}/openshell-sandbox /build/out/openshell-sandbox # Source-built path (local dev, BUILD_FROM_SOURCE=1) FROM rust-builder AS supervisor-binary-1 FROM supervisor-binary-${BUILD_FROM_SOURCE} AS supervisor-binary # --------------------------------------------------------------------------- # Final gateway image # --------------------------------------------------------------------------- FROM nvcr.io/nvidia/base/ubuntu:noble-20251013 AS gateway RUN apt-get update && apt-get install -y --no-install-recommends \ ca-certificates && \ apt-get install -y --only-upgrade gpgv && \ rm -rf /var/lib/apt/lists/* RUN useradd --create-home --user-group openshell WORKDIR /app COPY --from=gateway-binary /build/out/openshell-gateway /usr/local/bin/ RUN mkdir -p /build/crates/openshell-server COPY --chmod=755 crates/openshell-server/migrations /build/crates/openshell-server/migrations USER openshell EXPOSE 8080 ENTRYPOINT ["openshell-gateway"] CMD ["--bind-address", "0.0.0.0", "--port", "8080"] # --------------------------------------------------------------------------- # Final supervisor image # --------------------------------------------------------------------------- # Supervisor image based on the same NVIDIA Ubuntu base used by the gateway. # # Used by: # - Docker driver: binary is extracted from the image and run inside the # agent container. # - Podman driver: image is mounted as an OCI volume at /opt/openshell/bin. # - Kubernetes driver: image runs as an init container that invokes the # binary's `copy-self` subcommand to seed an emptyDir volume. # # An Ubuntu base provides glibc and the dynamic loader needed to exec the # dynamically linked binary. `FROM scratch` would be smaller but cannot run # the binary, breaking the Kubernetes init-container path. FROM nvcr.io/nvidia/base/ubuntu:noble-20251013 AS supervisor COPY --from=supervisor-binary /build/out/openshell-sandbox /openshell-sandbox