# syntax=docker/dockerfile:1
#
# =============================================================================
# plandb — the agentic task graph, pinned to an upstream release asset
#
# Upstream ships no container image. It ships checksummed release binaries
# (plandb-linux-<arch> plus checksums.txt). Downloading the pinned asset and
# verifying it against the published sha256 keeps the build reproducible and
# keeps a Rust toolchain out of this image entirely.
#
# The asset DYNAMICALLY links against glibc and needs **glibc >= 2.39**.
#
# `file` is NOT sufficient to determine this: it reports only the ELF ABI floor
# ("for GNU/Linux 3.2.0"), which is true of a binary that still fails at exec.
# The real requirement only appears when the binary runs:
#
#   plandb: /lib/x86_64-linux-gnu/libc.so.6:
#           version `GLIBC_2.39' not found (required by plandb)
#
# Bookworm is glibc 2.36 and fails exactly that way; Debian Trixie is 2.41 and
# satisfies it. Trixie is also this estate's current stable base. Musl/alpine
# cannot run this binary at all.
#
# The `plandb --version` below is therefore a required build-time smoke test,
# not decoration: it is the only thing that proves the base is new enough.
#
# `node:22-trixie-slim` is digest-pinned. It carries the glibc the binary needs
# and the runtime supergateway (the stdio to streamable-HTTP bridge, same tool
# as caveman/mcp-bridge) requires as an npm package.
# =============================================================================

FROM node:22-trixie-slim@sha256:2117f713a417f3aff682ac8f5bc2ebbdf1beed51f36e67ab1e0fd3866b6d2d8f

ARG PLANDB_VERSION=v0.2.1

# sha256 values copied from that release's own checksums.txt. A mismatch fails
# the build here rather than shipping a different binary than the one reviewed.
ARG PLANDB_SHA256_X86_64=ab9098caf13284579a8e8bc37a817f44baee73ace025a6520785a8ae175499a2
ARG PLANDB_SHA256_AARCH64=b511296a18471fb2508997a5466feb126c44ca0311f8f67a9bd198cfc4d2fc86
# Same release as caveman/mcp-bridge uses, so both bridges move together.
ARG SUPERGATEWAY_VERSION=3.4.3

SHELL ["/bin/bash", "-o", "pipefail", "-c"]

# ca-certificates and curl are runtime dependencies too: the healthcheck for the
# http service probes a real REST route, and TLS matters the moment an outbound
# call is added.
RUN apt-get update \
 && apt-get install -y --no-install-recommends ca-certificates curl \
 && rm -rf /var/lib/apt/lists/*

RUN set -eux; \
    case "${TARGETARCH:-amd64}" in \
      amd64) asset="plandb-linux-x86_64";  want="${PLANDB_SHA256_X86_64}"  ;; \
      arm64) asset="plandb-linux-aarch64"; want="${PLANDB_SHA256_AARCH64}" ;; \
      *)     echo "unsupported TARGETARCH: ${TARGETARCH}" >&2; exit 1 ;; \
    esac; \
    base="https://github.com/Agent-Field/plandb/releases/download/${PLANDB_VERSION}"; \
    curl -fsSL -o /usr/local/bin/plandb "${base}/${asset}"; \
    echo "${want}  /usr/local/bin/plandb" | sha256sum -c -; \
    chmod 0755 /usr/local/bin/plandb; \
    plandb --version

RUN npm install -g "supergateway@${SUPERGATEWAY_VERSION}" \
 && npm cache clean --force

# A fresh named volume inherits the ownership of the image path it is mounted
# over, so creating /data with the runtime uid is what makes the database
# writable without a chown-on-start sidecar. An ALREADY-CREATED volume keeps its
# old ownership — see README before recreating the volume by hand.
RUN install -d -o node -g node -m 0750 /data

ENV PLANDB_DB=/data/plandb.db
WORKDIR /data

# Belt and braces: even if an interface ignores PLANDB_DB, the default
# `.plandb.db` resolves inside /data because that is the working directory.
USER node

EXPOSE 8484

LABEL org.opencontainers.image.title="plandb" \
      org.opencontainers.image.description="Compound task graph for coding agents; MCP bridge and REST server" \
      org.opencontainers.image.version="${PLANDB_VERSION}"

# Default to the REST server; the compose file overrides this for the bridge.
CMD ["plandb", "serve", "--db", "/data/plandb.db", "--port", "8484"]
