# Dockerfile — MCIAS multi-stage container image # # Stage 1 (builder): Compiles all four MCIAS binaries. # Stage 2 (runtime): Minimal Debian image containing only the binaries. # # The final image: # - Runs as non-root uid 10001 (mcias) # - Exposes port 8443 (REST/TLS) and 9443 (gRPC/TLS) # - Declares VOLUME /data for the SQLite database # - Does NOT contain the Go toolchain, source code, or build cache # # Build: # docker build -t mcias:$(git describe --tags --always) . # # Run: # docker run -d \ # --name mcias \ # -v /path/to/config:/etc/mcias:ro \ # -v mcias-data:/data \ # -e MCIAS_MASTER_PASSPHRASE=your-passphrase \ # -p 8443:8443 \ # -p 9443:9443 \ # mcias:latest # --------------------------------------------------------------------------- # Stage 1 — builder # --------------------------------------------------------------------------- FROM golang:1.26-bookworm AS builder WORKDIR /build # Download dependencies first for layer caching. COPY go.mod go.sum ./ RUN go mod download # Copy source. COPY . . # CGO_ENABLED=1 is required by modernc.org/sqlite (pure-Go CGo-free SQLite). # -trimpath removes local file system paths from the binary. # -ldflags="-s -w" strips the DWARF debug info and symbol table to reduce # image size. RUN CGO_ENABLED=1 go build -trimpath -ldflags="-s -w" -o /out/mciassrv ./cmd/mciassrv && \ CGO_ENABLED=1 go build -trimpath -ldflags="-s -w" -o /out/mciasctl ./cmd/mciasctl && \ CGO_ENABLED=1 go build -trimpath -ldflags="-s -w" -o /out/mciasdb ./cmd/mciasdb && \ CGO_ENABLED=1 go build -trimpath -ldflags="-s -w" -o /out/mciasgrpcctl ./cmd/mciasgrpcctl # --------------------------------------------------------------------------- # Stage 2 — runtime # --------------------------------------------------------------------------- FROM debian:bookworm-slim # Install runtime dependencies. # ca-certificates: required to validate external TLS certificates. # libc6: required by CGo-compiled binaries (sqlite). RUN apt-get update && \ apt-get install -y --no-install-recommends \ ca-certificates \ libc6 && \ rm -rf /var/lib/apt/lists/* # Create a non-root user for the service. # uid/gid 10001 is chosen to be well above the range typically assigned to # system users (1–999) and human users (1000+), reducing the chance of # collision with existing uids on the host when using host networking. RUN groupadd --gid 10001 mcias && \ useradd --uid 10001 --gid 10001 --no-create-home --shell /usr/sbin/nologin mcias # Copy compiled binaries from the builder stage. COPY --from=builder /out/mciassrv /usr/local/bin/mciassrv COPY --from=builder /out/mciasctl /usr/local/bin/mciasctl COPY --from=builder /out/mciasdb /usr/local/bin/mciasdb COPY --from=builder /out/mciasgrpcctl /usr/local/bin/mciasgrpcctl # Create the config and data directories. # /etc/mcias is mounted read-only by the operator with the config file, # TLS cert, and TLS key. # /data is the SQLite database mount point. RUN mkdir -p /etc/mcias /data && \ chown mcias:mcias /data && \ chmod 0750 /data # Declare /data as a volume so the operator must explicitly mount it. # The SQLite database must persist across container restarts. VOLUME /data # REST/TLS port and gRPC/TLS port. These are documentation only; the actual # ports are set in the config file. Override by mounting a different config. EXPOSE 8443 EXPOSE 9443 # Run as the non-root mcias user. USER mcias # Default entry point and config path. # The operator mounts /etc/mcias/mcias.conf from the host or a volume. # See dist/mcias.conf.docker.example for a suitable template. ENTRYPOINT ["mciassrv"] CMD ["-config", "/etc/mcias/mcias.conf"]