-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathContainerfile
More file actions
104 lines (90 loc) · 4.64 KB
/
Copy pathContainerfile
File metadata and controls
104 lines (90 loc) · 4.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# SPDX-License-Identifier: MPL-2.0
# Containerfile - K9 SVC Runtime Container
#
# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath)
#
# Uses Chainguard base images for minimal attack surface:
# - Builder stage: Rust toolchain on wolfi-base for compiling nickel and just
# - Runtime stage: wolfi-base with only the binaries needed to run k9 components
#
# Chainguard images have no shell (in static variants), no package manager
# bloat, and minimal CVE surface. We use wolfi-base (not static) because
# k9-svc needs a shell for the must shim and Just recipes.
#
# Build: podman build -t k9-svc:latest .
# Run: podman run --rm -it k9-svc:latest status
# Mount: podman run --rm -it -v ./components:/k9/components k9-svc:latest validate-all
# ─────────────────────────────────────────────────────────────────────
# Builder Stage
#
# Compiles nickel-lang-cli and just from source using Rust.
# This stage is discarded after the binaries are copied out.
# ─────────────────────────────────────────────────────────────────────
FROM cgr.dev/chainguard/wolfi-base:latest AS builder
# Install build dependencies via apk (wolfi's package manager).
# - rust and cargo for compiling nickel and just
# - curl and ca-certificates for downloading crate dependencies
# - gcc and musl-dev for linking native code
RUN apk update && apk add --no-cache \
rust \
cargo \
curl \
ca-certificates \
gcc \
musl-dev
# Install Nickel (the typed configuration language that powers k9 validation)
RUN cargo install nickel-lang-cli --locked
# Install Just (the task runner that powers k9 recipes)
RUN cargo install just --locked
# ─────────────────────────────────────────────────────────────────────
# Runtime Stage
#
# Minimal Chainguard image with only the binaries and files needed
# to run k9 components. No build tools, no package manager bloat.
# ─────────────────────────────────────────────────────────────────────
FROM cgr.dev/chainguard/wolfi-base:latest
LABEL org.opencontainers.image.title="K9 SVC Runtime"
LABEL org.opencontainers.image.description="Self-Validating Component runtime environment"
LABEL org.opencontainers.image.version="1.0.0-alpha"
LABEL org.opencontainers.image.vendor="hyperpolymath"
LABEL org.opencontainers.image.licenses="MPL-2.0"
LABEL org.opencontainers.image.source="https://github.com/hyperpolymath/standards/tree/main/k9-svc"
# Install minimal runtime dependencies via apk.
# - ca-certificates: for TLS verification when Hunt components access network
# - file: for MIME type detection (used by `file --mime-type` in k9 validation)
# - libgcc: runtime library needed by compiled Rust binaries
RUN apk update && apk add --no-cache \
ca-certificates \
file \
libgcc
# Create non-root user for security.
# k9 components should never run as root unless explicitly required
# by a Hunt-level component (and even then, avoid it).
RUN adduser -D -s /bin/sh k9user
USER k9user
WORKDIR /home/k9user/k9
# Copy binaries from builder stage.
# Only nickel and just are needed at runtime — no Rust toolchain.
COPY --from=builder /root/.cargo/bin/nickel /usr/local/bin/nickel
COPY --from=builder /root/.cargo/bin/just /usr/local/bin/just
# Copy K9 SVC files into the container.
# These are the core schemas, the must shim, and the examples.
COPY --chown=k9user:k9user must justfile pedigree.ncl register.ncl leash.ncl ./
COPY --chown=k9user:k9user mime/ ./mime/
COPY --chown=k9user:k9user examples/ ./examples/
# Verify the triad is functional.
# This is the dogfooding step: the container validates itself during build.
# If any of these fail, the build fails — no broken images ship.
RUN ./must status && \
nickel typecheck pedigree.ncl && \
nickel typecheck register.ncl && \
nickel typecheck leash.ncl
# Default entrypoint: the must shim, which detects the environment
# and delegates to just/nickel as appropriate.
ENTRYPOINT ["./must"]
CMD ["status"]
# Volume for mounting external components.
# Users mount their .k9 and .k9.ncl files here for validation/deployment.
VOLUME ["/home/k9user/k9/components"]
# Expose nothing by default (K9 is not a server).
# Hunt-level components that need ports can override this.