Publish documentation / publish (push) Successful in 1m27s
Add PostgreSQL-backed memory, editable evidence with source review and activation, and human-approved archive repairs across the harness, API, and UI. Include migrations, deployment support, regression coverage, and validation documentation. Refresh permissions from validated session roles so existing administrator logins can access newly deployed archive management features.
146 lines
7.7 KiB
Docker
146 lines
7.7 KiB
Docker
# syntax=docker/dockerfile:1.7
|
|
# thothii-core: Fastify (Node 24.16) + harness Python 3.12 (tht CLI) + runtime Pi.
|
|
# Singolo container, entrypoint logico "server" (default).
|
|
ARG PI_VERSION=0.80.3
|
|
ARG IMAGE_VERSION=local
|
|
|
|
# ---- Pinned Node source for the runtime binary and npm ----
|
|
FROM node:24.16.0-bookworm@sha256:40ad9f3064e67d6860b4bc3fe1880b2953934fd6320ada990e45fe0efa6badd7 AS node-runtime
|
|
|
|
# ---- Pinned native storage helper used by the authenticated backend ----
|
|
FROM golang:1.26.5-bookworm@sha256:1ecb7edf62a0408027bd5729dfd6b1b8766e578e8df93995b225dfd0944eb651 AS tht-auth-storage-build
|
|
WORKDIR /src/tools/tht
|
|
COPY tools/tht/go.mod tools/tht/go.sum ./
|
|
RUN go mod download
|
|
COPY tools/tht ./
|
|
RUN CGO_ENABLED=0 go build -trimpath -ldflags='-s -w' -o /out/tht-auth-storage ./cmd/tht
|
|
|
|
# ---- Stage 0: locked Pi runtime ----
|
|
FROM node:24.16.0-bookworm@sha256:40ad9f3064e67d6860b4bc3fe1880b2953934fd6320ada990e45fe0efa6badd7 AS pi-runtime-build
|
|
ARG PI_VERSION
|
|
ARG PI_RUNTIME_PACKAGE_VERSION
|
|
ARG PI_PACKAGE_NAME=@earendil-works/pi-coding-agent
|
|
WORKDIR /opt/pi-runtime
|
|
COPY docker/pi-runtime/package.json docker/pi-runtime/package-lock.json ./
|
|
RUN if [ -n "$PI_RUNTIME_PACKAGE_VERSION" ]; then \
|
|
node -e 'const fs=require("node:fs"); const [name,version]=process.argv.slice(1); const manifest=JSON.parse(fs.readFileSync("package.json","utf8")); manifest.dependencies[name]=version; fs.writeFileSync("package.json",JSON.stringify(manifest,null,2)+"\\n");' "$PI_PACKAGE_NAME" "$PI_RUNTIME_PACKAGE_VERSION"; \
|
|
npm install --package-lock-only --ignore-scripts --omit=dev "$PI_PACKAGE_NAME@$PI_RUNTIME_PACKAGE_VERSION"; \
|
|
fi \
|
|
&& npm ci --omit=dev \
|
|
&& test "$(./node_modules/.bin/pi --version)" = "$PI_VERSION"
|
|
|
|
# ---- Stage 1: backend TypeScript -> dist ----
|
|
FROM node:24.16.0-bookworm@sha256:40ad9f3064e67d6860b4bc3fe1880b2953934fd6320ada990e45fe0efa6badd7 AS backend-build
|
|
WORKDIR /src/backend
|
|
COPY backend/package*.json ./
|
|
RUN npm ci
|
|
COPY backend/ ./
|
|
RUN npm run build
|
|
|
|
# ---- Stage 2: runtime (Python 3.12 nativo + Node 24.16 copiato, stesso glibc bookworm) ----
|
|
FROM python:3.12-slim-bookworm@sha256:d50fb7611f86d04a3b0471b46d7557818d88983fc3136726336b2a4c657aa30b AS runtime
|
|
ARG PI_VERSION
|
|
ARG IMAGE_VERSION
|
|
ARG INSTALL_SENSITIVITY_NER=false
|
|
LABEL org.opencontainers.image.title="thothii-core" \
|
|
org.opencontainers.image.version="${IMAGE_VERSION}" \
|
|
org.opencontainers.image.description="ThothII core with its embedded Pi runtime" \
|
|
io.thothii.pi.version="${PI_VERSION}"
|
|
|
|
# Runtime tools
|
|
RUN set -eux; \
|
|
runtime_packages="curl ca-certificates ripgrep fd-find tini git openssh-client libseccomp2"; \
|
|
if ! command -v flock >/dev/null 2>&1; then \
|
|
runtime_packages="$runtime_packages util-linux"; \
|
|
fi; \
|
|
apt-get update; \
|
|
apt-get install -y --no-install-recommends $runtime_packages; \
|
|
rm -rf /var/lib/apt/lists/*; \
|
|
command -v flock >/dev/null 2>&1; \
|
|
ln -s /usr/bin/fdfind /usr/local/bin/fd
|
|
|
|
# Node 24.16 + npm copiati dall'immagine ufficiale (stesso Debian bookworm → binario compatibile)
|
|
COPY --from=node-runtime /usr/local/bin/node /usr/local/bin/node
|
|
COPY --from=node-runtime /usr/local/lib/node_modules /usr/local/lib/node_modules
|
|
RUN ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \
|
|
&& ln -s /usr/local/lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx
|
|
|
|
# Utente non-root
|
|
RUN useradd --create-home --uid 10001 --shell /bin/bash thoth
|
|
# Docker copies these owned directories into newly-created named volumes, allowing the non-root
|
|
# runtime user to create application settings, sessions, registry snapshots, state, and locks.
|
|
RUN mkdir -p /home/thoth/.pi/agent /data/settings /data/sessions /data/workspace-registry /data/workspace-secrets \
|
|
/data/auth/sessions /data/auth/oidc \
|
|
&& chown -R thoth:thoth /home/thoth/.pi /data \
|
|
&& chmod 0700 /data/auth /data/auth/sessions /data/auth/oidc
|
|
|
|
COPY harness/ /app/harness/
|
|
# Pi scrive lock/settings in .pi: ownership thoth per sopravvivere al rebuild
|
|
RUN chown -R thoth:thoth /app/harness/.pi
|
|
|
|
# Harness: venv nativo (python 3.12) + tht installato (non-editable).
|
|
# tht carica workflow.yaml module-relative (Path(__file__).parent.parent); con il package
|
|
# in site-packages quel path non contiene workflow.yaml -> lo copiamo dopo l'install.
|
|
# (pip install -e non funziona: pip non riconosce /app/harness come editable req.)
|
|
# psycopg2-binary è wheel → niente gcc/libpq-dev.
|
|
RUN python -m venv /opt/venv \
|
|
&& /opt/venv/bin/pip install --no-cache-dir --upgrade pip \
|
|
&& (cd /app/harness && /opt/venv/bin/pip install --no-cache-dir .) \
|
|
&& cp /app/harness/workflow.yaml /opt/venv/lib/python3.12/site-packages/workflow.yaml
|
|
# Il workspace locale predefinito converge sul file canonico. Il CLI onora anche THT_CONFIG,
|
|
# quindi cambiare CWD non cambia l'identita' dello workspace.
|
|
RUN mkdir -p /app/harness/config \
|
|
&& cp --remove-destination /app/harness/workspaces/local.yaml /app/harness/config/tht.yaml
|
|
# PiProcessManager (backend) prepende harnessDir/.venv/bin al PATH del child Pi → symlink al venv reale
|
|
RUN ln -s /opt/venv /app/harness/.venv
|
|
|
|
# The optional NER dependency layer is independent of backend source and build artifacts so it can
|
|
# be reused when only TypeScript or worker code changes.
|
|
COPY backend/python/sensitivity-ner-requirements.txt /app/backend/python/sensitivity-ner-requirements.txt
|
|
RUN if [ "$INSTALL_SENSITIVITY_NER" = "true" ]; then \
|
|
python -m venv /opt/sensitivity-ner; \
|
|
/opt/sensitivity-ner/bin/pip install --no-cache-dir --upgrade pip; \
|
|
/opt/sensitivity-ner/bin/pip install --no-cache-dir -r /app/backend/python/sensitivity-ner-requirements.txt; \
|
|
elif [ "$INSTALL_SENSITIVITY_NER" != "false" ]; then \
|
|
echo "INSTALL_SENSITIVITY_NER must be true or false" >&2; exit 2; \
|
|
fi
|
|
|
|
# Backend: dist + node_modules (stesso Node major 24 + glibc bookworm → compatibili)
|
|
COPY --from=backend-build /src/backend/dist /app/backend/dist
|
|
COPY --from=backend-build /src/backend/node_modules /app/backend/node_modules
|
|
COPY backend/scripts/ssh-askpass.mjs /app/backend/scripts/ssh-askpass.mjs
|
|
COPY backend/python /app/backend/python
|
|
COPY backend/package*.json /app/backend/
|
|
RUN chmod 0755 /app/backend/scripts/ssh-askpass.mjs
|
|
|
|
# Runtime Pi is installed only from the committed lockfile. The image exposes its immutable
|
|
# executable directly, so no host Pi installation or writable global npm directory is needed.
|
|
COPY --from=pi-runtime-build /opt/pi-runtime/node_modules /opt/pi-runtime/node_modules
|
|
COPY --from=tht-auth-storage-build /out/tht-auth-storage /usr/local/bin/tht-auth-storage
|
|
RUN ln -s /opt/pi-runtime/node_modules/.bin/pi /usr/local/bin/pi \
|
|
&& test "$(pi --version)" = "$PI_VERSION" \
|
|
&& test -x /usr/local/bin/tht-auth-storage
|
|
|
|
ENV PATH="/opt/venv/bin:/usr/local/bin:$PATH" \
|
|
PI_VERSION="${PI_VERSION}" \
|
|
HOST=0.0.0.0 PORT=8787 \
|
|
THT_HARNESS_DIR=/app/harness \
|
|
THT_BIN=/opt/venv/bin/tht \
|
|
THT_AUTH_STORAGE_BIN=/usr/local/bin/tht-auth-storage \
|
|
PI_BIN=pi \
|
|
HOME=/home/thoth
|
|
|
|
COPY scripts/verify-line-endings.sh /usr/local/bin/verify-line-endings
|
|
COPY docker/core-entrypoint.sh docker/workspace-maintenance-entrypoint.sh docker/session-migrate.sh docker/catalog-migrate.sh docker/ensure-pi-trust.mjs docker/embedding-model-init.sh /app/docker/
|
|
COPY docker/smoke/core-smoke.sh /app/docker/smoke/core-smoke.sh
|
|
RUN /usr/local/bin/verify-line-endings /app/docker \
|
|
&& chmod +x /app/docker/core-entrypoint.sh /app/docker/workspace-maintenance-entrypoint.sh /app/docker/session-migrate.sh /app/docker/embedding-model-init.sh /app/docker/smoke/core-smoke.sh
|
|
|
|
WORKDIR /app/backend
|
|
USER thoth
|
|
EXPOSE 8787
|
|
HEALTHCHECK --interval=15s --timeout=3s --retries=5 --start-period=30s \
|
|
CMD curl -fsS http://127.0.0.1:8787/health || exit 1
|
|
ENTRYPOINT ["/usr/bin/tini","--","/app/docker/core-entrypoint.sh"]
|
|
CMD ["server"]
|