mirror of
https://github.com/NVIDIA/OpenShell.git
synced 2026-10-21 06:11:31 +08:00
Pass the computed cargo version through Docker and cluster packaging paths so deployed clusters report the built artifact version while keeping latest and explicit version tags aligned.
105 lines
4.8 KiB
Docker
105 lines
4.8 KiB
Docker
# syntax=docker/dockerfile:1.4
|
|
|
|
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
# NemoClaw Server 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 NEMOCLAW_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/navigator-cli/Cargo.toml crates/navigator-cli/Cargo.toml
|
|
COPY crates/navigator-core/Cargo.toml crates/navigator-core/Cargo.toml
|
|
COPY crates/navigator-providers/Cargo.toml crates/navigator-providers/Cargo.toml
|
|
COPY crates/navigator-router/Cargo.toml crates/navigator-router/Cargo.toml
|
|
COPY crates/navigator-sandbox/Cargo.toml crates/navigator-sandbox/Cargo.toml
|
|
COPY crates/navigator-server/Cargo.toml crates/navigator-server/Cargo.toml
|
|
COPY crates/navigator-bootstrap/Cargo.toml crates/navigator-bootstrap/Cargo.toml
|
|
|
|
# Create dummy source files to build dependencies
|
|
RUN mkdir -p crates/navigator-cli/src crates/navigator-core/src crates/navigator-providers/src crates/navigator-router/src crates/navigator-sandbox/src crates/navigator-server/src crates/navigator-bootstrap/src && \
|
|
echo "fn main() {}" > crates/navigator-cli/src/main.rs && \
|
|
echo "fn main() {}" > crates/navigator-sandbox/src/main.rs && \
|
|
echo "fn main() {}" > crates/navigator-server/src/main.rs && \
|
|
touch crates/navigator-core/src/lib.rs && \
|
|
touch crates/navigator-providers/src/lib.rs && \
|
|
touch crates/navigator-router/src/lib.rs && \
|
|
touch crates/navigator-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-server-${TARGETARCH},sharing=locked,target=/usr/local/cargo/registry \
|
|
--mount=type=cache,id=cargo-target-server-${TARGETARCH}-${CARGO_TARGET_CACHE_SCOPE},sharing=locked,target=/build/target \
|
|
--mount=type=cache,id=sccache-server-${TARGETARCH},sharing=locked,target=/tmp/sccache \
|
|
. cross-build.sh && cargo_cross_build --release -p navigator-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/navigator-server/src/main.rs \
|
|
crates/navigator-core/build.rs \
|
|
proto/*.proto
|
|
|
|
# Build the actual application
|
|
RUN --mount=type=cache,id=cargo-registry-server-${TARGETARCH},sharing=locked,target=/usr/local/cargo/registry \
|
|
--mount=type=cache,id=cargo-target-server-${TARGETARCH}-${CARGO_TARGET_CACHE_SCOPE},sharing=locked,target=/build/target \
|
|
--mount=type=cache,id=sccache-server-${TARGETARCH},sharing=locked,target=/tmp/sccache \
|
|
. cross-build.sh && \
|
|
if [ -n "${NEMOCLAW_CARGO_VERSION:-}" ]; then \
|
|
sed -i -E '/^\[workspace\.package\]/,/^\[/{s/^version[[:space:]]*=[[:space:]]*".*"/version = "'"${NEMOCLAW_CARGO_VERSION}"'"/}' Cargo.toml; \
|
|
fi && \
|
|
cargo_cross_build --release -p navigator-server && \
|
|
cp "$(cross_output_dir release)/navigator-server" /build/navigator-server
|
|
|
|
# Stage 2: Runtime (uses target platform)
|
|
FROM debian:bookworm-slim 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 navigator
|
|
|
|
WORKDIR /app
|
|
|
|
COPY --from=builder /build/navigator-server /usr/local/bin/
|
|
|
|
# Copy migrations to the build-time manifest directory expected by sqlx
|
|
RUN mkdir -p /build/crates/navigator-server
|
|
COPY crates/navigator-server/migrations /build/crates/navigator-server/migrations
|
|
|
|
USER navigator
|
|
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 ["navigator-server"]
|
|
CMD ["--port", "8080"]
|