# Copyright 2025 Clidey, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # WhoDB CLI Dockerfile FROM golang:1.27.3-alpine3.24 AS builder SHELL ["/bin/ash", "-eo", "pipefail", "-c"] ARG VERSION=dev RUN apk add --no-cache gcc g++ musl-dev git bash curl binutils upx # DuckDB's pre-built static library references glibc-specific symbols unavailable in musl. # Build a static compat library so the linker deduplicates across CGO packages. RUN printf '#include \nint __res_init(void) { return 0; }\nint backtrace(void **b, int s) { return 0; }\nchar **backtrace_symbols(void *const *b, int s) { return NULL; }\nvoid backtrace_symbols_fd(void *const *b, int s, int fd) {}\nint malloc_trim(size_t pad) { return 0; }\n' \ | gcc -c -x c - -o /tmp/duckdb_musl_compat.o \ && ar rcs /usr/lib/libduckdb_musl_compat.a /tmp/duckdb_musl_compat.o WORKDIR /app # Copy core module COPY core/go.mod core/go.sum ./core/ WORKDIR /app/core RUN --mount=type=cache,target=/go/pkg/mod \ --mount=type=cache,target=/root/.cache/go-build \ go mod download # Copy cli module WORKDIR /app COPY cli/go.mod cli/go.sum ./cli/ WORKDIR /app/cli RUN --mount=type=cache,target=/go/pkg/mod \ --mount=type=cache,target=/root/.cache/go-build \ go mod download # Copy all source code WORKDIR /app COPY core/ ./core/ COPY cli/ ./cli/ # Build CLI binary with version injection WORKDIR /app/cli ARG TARGETARCH RUN --mount=type=cache,target=/go/pkg/mod \ --mount=type=cache,target=/root/.cache/go-build \ CGO_CFLAGS="-Os -ffunction-sections -fdata-sections -fno-asynchronous-unwind-tables -fno-unwind-tables -flto -fvisibility=hidden" \ CGO_LDFLAGS="-Wl,--gc-sections -Wl,--as-needed -flto -lduckdb_musl_compat" \ CGO_ENABLED=1 GOOS=linux GOARCH=${TARGETARCH} go build -trimpath \ -ldflags "-s -w -X github.com/clidey/whodb/cli/pkg/version.Version=${VERSION}" \ -o /whodb . RUN chmod +x /whodb && \ upx --best /whodb # Pre-download BAML native library for the target architecture (musl for Alpine) # Extract BAML version from go.mod to stay in sync RUN BAML_VERSION=$(grep 'github.com/boundaryml/baml ' /app/core/go.mod | awk '{print $2}' | sed 's/^v//') && \ if [ "$TARGETARCH" = "amd64" ]; then \ BAML_ARCH="x86_64"; \ elif [ "$TARGETARCH" = "arm64" ]; then \ BAML_ARCH="aarch64"; \ else \ echo "Unsupported architecture: $TARGETARCH" && exit 1; \ fi && \ mkdir -p /baml-lib && \ curl --fail --location --retry 3 -o /baml-lib/libbaml_cffi.so \ https://github.com/boundaryml/baml/releases/download/${BAML_VERSION}/libbaml_cffi-${BAML_ARCH}-unknown-linux-musl.so && \ chmod +x /baml-lib/libbaml_cffi.so && \ strip --strip-debug /baml-lib/libbaml_cffi.so && \ echo "Downloaded BAML musl library for ${BAML_ARCH}" # Final stage FROM alpine:3.24 RUN apk add --no-cache ca-certificates libgcc libstdc++ WORKDIR /app COPY --from=builder /whodb /usr/local/bin/whodb # Deprecated alias for "whodb", kept for existing scripts. It prints a # warning (via argv0 detection in the binary) and will be removed in a # future release. RUN ln -s /usr/local/bin/whodb /usr/local/bin/whodb-cli # Copy BAML musl library and set path via env var COPY --from=builder /baml-lib/libbaml_cffi.so /usr/local/lib/libbaml_cffi.so ENV BAML_LIBRARY_PATH=/usr/local/lib/libbaml_cffi.so # Create config directory RUN mkdir -p /root/.whodb-cli ENTRYPOINT ["whodb"] CMD ["--help"]