Dockerfile
Rama main · réplica de lectura del repositorio original.
# Copyright (c) 2026 CueCrux Ltd.
# Licensed under the Apache License, Version 2.0.
# --- Builder stage ---
# Chainguard exception (workspace CLAUDE.md §9): the build stage stays on the
# upstream `rust` image because the workspace pins its toolchain via
# rust-toolchain.toml (channel 1.88.0) and needs rustup to honour that pin;
# cgr.dev/chainguard/rust free tier is :latest-only (floating toolchain), which
# would silently drift the compiler under a pinned, reproducible release build.
FROM rust:1.88-bookworm AS builder
RUN apt-get update && apt-get install -y protobuf-compiler && rm -rf /var/lib/apt/lists/*
WORKDIR /build
COPY Cargo.toml Cargo.lock rust-toolchain.toml ./
COPY crates/ crates/
COPY proto/ proto/
# corecruxctl embeds integrations/claude-code/hooks/crux-observe.sh via
# include_str! (the `corecruxctl hooks install` asset), so it must be present in
# the build context for the release build to compile.
COPY integrations/ integrations/
# Git sha for `corecruxd --version` / the boot banner. The build context does
# NOT include `.git`, so corecruxd's build.rs cannot derive it via `git` here —
# the CI Docker workflow passes it as a build-arg. Defaults to `unknown` for a
# plain `docker build` with no arg.
ARG GIT_SHA=unknown
ENV CORECRUX_GIT_SHA=${GIT_SHA}
# Release version: the v2 console reports the version at runtime (via the daemon
# API), so no build-time HTML stamping is needed. RELEASE_VERSION is retained as
# an accepted build-arg for CI compatibility (the removed v1 console footer used
# a `__CRUX_RELEASE__` placeholder; v2 has none).
ARG RELEASE_VERSION=
RUN cargo build --locked --release --bin corecruxd --bin corecruxctl
# --- Runtime stage ---
# Chainguard wolfi-base (CLAUDE.md §9): rebuilt daily, zero-known-CVE target,
# minimal package set. Free tier requires the :latest tag (accepted).
FROM cgr.dev/chainguard/wolfi-base:latest
# Runtime packages:
# - ca-certificates: TLS trust for optional *opt-in* outbound features (sync,
# remote embedding endpoints). The daemon dials nothing by default — see
# scripts/assert-no-phone-home.sh.
# - curl: container HEALTHCHECK probe.
# - git: the update-posture probe (update.rs) shells out to `git fetch`/
# `git rev-list` against the /repo bind mount on repo-checkout deploys to
# compute ahead/behind. Without git the fetch silently fails and the banner
# reports a confidently-wrong drift count from the stale cached tracking ref.
RUN apk add --no-cache ca-certificates curl git
COPY --from=builder /build/target/release/corecruxd /usr/local/bin/corecruxd
COPY --from=builder /build/target/release/corecruxctl /usr/local/bin/corecruxctl
# Apache-2.0 sections 4(a) and 4(d): a redistribution must carry the licence and
# the NOTICE attribution. The image ships binaries only, so the per-file source
# headers do not travel with it — these two files are what satisfy the condition.
COPY LICENSE NOTICE /usr/share/doc/crux-daemon/
# Non-root runtime user: wolfi-base ships `nonroot` (uid/gid 65532), the
# Chainguard/distroless convention. /data ownership transfers to named volumes
# on first use (bind-mount users must chown the host dir themselves — see
# examples/quickstart/README.md).
RUN mkdir -p /data && chown -R 65532:65532 /data
ENV CORECRUXD_DATA_DIR=/data
ENV CORECRUXD_BUILD_CCXI=1
ENV CORECRUX_LOG_FORMAT=json
EXPOSE 14800
HEALTHCHECK --interval=10s --timeout=5s --retries=3 \
CMD curl -f http://localhost:14800/readyz || exit 1
VOLUME ["/data"]
USER 65532:65532
CMD ["corecruxd"]