# syntax=docker/dockerfile:1.4 # SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 # OpenShell Gateway Docker image # Multi-stage build with cross-compilation support for multi-arch # Stage 1: Rust builder (runs on build platform, cross-compiles for target) FROM --platform=$BUILDPLATFORM rust:1.88-slim AS builder ARG TARGETARCH ARG BUILDARCH ARG OPENSHELL_CARGO_VERSION ARG CARGO_TARGET_CACHE_SCOPE=default # Install build dependencies RUN apt-get update && apt-get install -y --no-install-recommends \ cmake g++ make protobuf-compiler curl && rm -rf /var/lib/apt/lists/* # Install cross-compilation toolchain, sccache, + Rust target (no-ops for native builds) COPY deploy/docker/cross-build.sh /usr/local/bin/ RUN . cross-build.sh && install_cross_toolchain && install_sccache && add_rust_target ARG SCCACHE_MEMCACHED_ENDPOINT WORKDIR /build # Copy dependency manifests first for better caching COPY Cargo.toml Cargo.lock ./ COPY crates/openshell-cli/Cargo.toml crates/openshell-cli/Cargo.toml COPY crates/openshell-core/Cargo.toml crates/openshell-core/Cargo.toml COPY crates/openshell-providers/Cargo.toml crates/openshell-providers/Cargo.toml COPY crates/openshell-router/Cargo.toml crates/openshell-router/Cargo.toml COPY crates/openshell-sandbox/Cargo.toml crates/openshell-sandbox/Cargo.toml COPY crates/openshell-server/Cargo.toml crates/openshell-server/Cargo.toml COPY crates/openshell-bootstrap/Cargo.toml crates/openshell-bootstrap/Cargo.toml # Create dummy source files to build dependencies RUN mkdir -p crates/openshell-cli/src crates/openshell-core/src crates/openshell-providers/src crates/openshell-router/src crates/openshell-sandbox/src crates/openshell-server/src crates/openshell-bootstrap/src && \ echo "fn main() {}" > crates/openshell-cli/src/main.rs && \ echo "fn main() {}" > crates/openshell-sandbox/src/main.rs && \ echo "fn main() {}" > crates/openshell-server/src/main.rs && \ touch crates/openshell-core/src/lib.rs && \ touch crates/openshell-providers/src/lib.rs && \ touch crates/openshell-router/src/lib.rs && \ touch crates/openshell-bootstrap/src/lib.rs # Copy proto files needed for build COPY proto/ proto/ # Build dependencies only (cached unless Cargo.toml/lock changes). # sccache uses memcached in CI (SCCACHE_MEMCACHED_ENDPOINT) or the local # disk cache mount for local dev builds. The cargo-target mount gives cargo # a persistent target/ dir for true incremental rebuilds on source changes. RUN --mount=type=cache,id=cargo-registry-gateway-${TARGETARCH},sharing=locked,target=/usr/local/cargo/registry \ --mount=type=cache,id=cargo-target-gateway-${TARGETARCH}-${CARGO_TARGET_CACHE_SCOPE},sharing=locked,target=/build/target \ --mount=type=cache,id=sccache-gateway-${TARGETARCH},sharing=locked,target=/tmp/sccache \ . cross-build.sh && cargo_cross_build --release -p openshell-server 2>/dev/null || true # Copy actual source code COPY crates/ crates/ # Touch source files to ensure they're rebuilt (not the cached dummy). # Touch build.rs and proto files to force proto code regeneration when the # cargo target cache mount retains stale OUT_DIR artifacts from prior builds. RUN touch crates/openshell-server/src/main.rs \ crates/openshell-core/build.rs \ proto/*.proto # Build the actual application RUN --mount=type=cache,id=cargo-registry-gateway-${TARGETARCH},sharing=locked,target=/usr/local/cargo/registry \ --mount=type=cache,id=cargo-target-gateway-${TARGETARCH}-${CARGO_TARGET_CACHE_SCOPE},sharing=locked,target=/build/target \ --mount=type=cache,id=sccache-gateway-${TARGETARCH},sharing=locked,target=/tmp/sccache \ . cross-build.sh && \ if [ -n "${OPENSHELL_CARGO_VERSION:-}" ]; then \ sed -i -E '/^\[workspace\.package\]/,/^\[/{s/^version[[:space:]]*=[[:space:]]*".*"/version = "'"${OPENSHELL_CARGO_VERSION}"'"/}' Cargo.toml; \ fi && \ cargo_cross_build --release -p openshell-server && \ cp "$(cross_output_dir release)/openshell-server" /build/openshell-server # Stage 2: Runtime (uses target platform) # NVIDIA hardened Ubuntu base for supply chain consistency. FROM nvcr.io/nvidia/base/ubuntu:noble-20251013 AS runtime RUN apt-get update && apt-get install -y --no-install-recommends \ ca-certificates && rm -rf /var/lib/apt/lists/* RUN useradd --create-home --user-group openshell WORKDIR /app COPY --from=builder /build/openshell-server /usr/local/bin/ # Copy migrations to the build-time manifest directory expected by sqlx RUN mkdir -p /build/crates/openshell-server COPY crates/openshell-server/migrations /build/crates/openshell-server/migrations USER openshell EXPOSE 8080 # Health checks are handled by Kubernetes liveness/readiness probes (tcpSocket). # No Docker HEALTHCHECK is needed since this image runs inside a k3s cluster. ENTRYPOINT ["openshell-server"] CMD ["--port", "8080"]