Files
harmony/fleet/harmony-fleet-operator/Dockerfile
Sylvain Tremblay 46ac4a572a feat(fleet): local-run scripts for example_fleet_server_install + glibc fix
Two scripts for running the new install Score against a local cluster:

- examples/fleet_server_install/run.sh — generic, cwd-independent
  passthrough around `cargo run -p example_fleet_server_install`.
- fleet/scripts/run_server_install.sh — opinionated k3d test harness:
  creates `fleet-server-test` cluster if absent (with NATS port 4222
  mapped through klipper-lb), builds the operator image via
  build_docker.sh, sideloads it, runs the Score, and leaves the
  cluster up. Prints teardown + redeploy commands at the end. Header
  documents the helm-idempotency limitation: a rebuilt image won't
  redeploy on a second run unless `helm uninstall` is invoked first
  (HelmChartScore short-circuits on chart_version match). Proper fix
  is deferred — content-hash chart_version or a force_upgrade flag.

Dockerfile glibc pin: builder pinned to `rust:1.94-slim-bookworm`.
Unsuffixed `rust:slim` follows Debian's latest stable (trixie =
glibc 2.40), so binaries built there fail to start on the
`debian:bookworm-slim` runtime (glibc 2.36) with "GLIBC_2.39 not
found". Surfaced when running the new scripts end-to-end.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 16:02:23 -04:00

57 lines
2.4 KiB
Docker

# Multi-stage container build for harmony-fleet-operator.
#
# Build context is the workspace root (the operator's Cargo.toml has
# `path = "../../harmony"` deps, which only resolve when the whole
# workspace is in scope). Invoke from the repo root:
#
# docker build -f fleet/harmony-fleet-operator/Dockerfile \
# -t hub.nationtech.io/harmony/harmony-fleet-operator:<tag> .
#
# This replaces an earlier single-stage image that copied a host-built
# binary into archlinux:base — the archlinux choice was a glibc-ABI
# workaround for that host-build path. Building inside a pinned Rust
# image lets us use a matched debian-slim runtime instead.
#
# The builder and runtime stages must pin the same Debian release —
# unsuffixed `rust:slim` follows Debian's latest stable (trixie =
# glibc 2.40), so a binary built there fails to start on
# `debian:bookworm-slim` (glibc 2.36) with "GLIBC_2.39 not found".
# Both stages are pinned to bookworm here for a stable, matched ABI.
FROM docker.io/rust:1.94-slim-bookworm AS builder
# pkg-config + libssl-dev cover transitive native-tls/openssl-sys deps
# that surface during link; ca-certificates lets cargo fetch over TLS.
RUN apt-get update && apt-get install -y --no-install-recommends \
pkg-config \
ca-certificates \
libssl-dev \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY . .
RUN cargo build --release --locked -p harmony-fleet-operator
FROM docker.io/library/debian:bookworm-slim
# ca-certificates: outbound TLS to the K8s API and (optionally) NATS.
# kube + async-nats use rustls, so no libssl3 needed at runtime.
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
COPY --from=builder /app/target/release/harmony-fleet-operator /usr/local/bin/harmony-fleet-operator
# Non-root runtime. Pairs with the Pod's `securityContext.
# runAsNonRoot: true` in the helm chart — k8s admission rejects pods
# with that flag unless either the image declares a non-root USER or
# the Pod pins runAsUser. We deliberately don't pin runAsUser
# (OpenShift's restricted-v2 SCC assigns a namespace-specific UID and
# rejects fixed UIDs); the image's USER is the portable mechanism.
# 65532 is the `nonroot` UID convention used by distroless + many
# security-hardened base images.
USER 65532:65532
ENTRYPOINT ["/usr/local/bin/harmony-fleet-operator"]