build: make embedded pi images reproducible

This commit is contained in:
2026-08-04 16:19:04 +02:00
parent a248fb46d0
commit d42fdf4b71
10 changed files with 131 additions and 116 deletions
+26 -7
View File
@@ -2,6 +2,15 @@
# thothii-core: Fastify (Node 22) + harness Python 3.12 (tht CLI) + runtime Pi.
# Singolo container, entrypoint logico "server" (default).
ARG PI_VERSION=0.80.3
ARG IMAGE_VERSION=local
# ---- Stage 0: locked Pi runtime ----
FROM node:22-bookworm AS pi-runtime-build
ARG PI_VERSION
WORKDIR /opt/pi-runtime
COPY docker/pi-runtime/package.json docker/pi-runtime/package-lock.json ./
RUN npm ci --omit=dev \
&& test "$(./node_modules/.bin/pi --version)" = "$PI_VERSION"
# ---- Stage 1: backend TypeScript -> dist ----
FROM node:22-bookworm AS backend-build
@@ -14,6 +23,11 @@ RUN npm run build
# ---- Stage 2: runtime (Python 3.12 nativo + Node 22 copiato, stesso glibc bookworm) ----
FROM python:3.12-slim-bookworm AS runtime
ARG PI_VERSION
ARG IMAGE_VERSION
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 apt-get update && apt-get install -y --no-install-recommends \
@@ -29,10 +43,10 @@ RUN ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \
# Utente non-root
RUN useradd --create-home --uid 10001 --shell /bin/bash thoth
RUN mkdir -p /home/thoth/.pi/agent && chown -R thoth:thoth /home/thoth/.pi
# Docker copies this owned directory into a newly-created named volume, allowing the non-root
# runtime user to create the registry checkout, immutable snapshots, state, and locks.
RUN mkdir -p /data/workspace-registry && chown -R thoth:thoth /data/workspace-registry
# 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 \
&& chown -R thoth:thoth /home/thoth/.pi /data
COPY harness/ /app/harness/
# Pi scrive lock/settings in .pi: ownership thoth per sopravvivere al rebuild
@@ -60,10 +74,14 @@ COPY --from=backend-build /src/backend/dist /app/backend/dist
COPY --from=backend-build /src/backend/node_modules /app/backend/node_modules
COPY backend/package*.json /app/backend/
# Runtime Pi (pacchetto npm puro JS, dipendenze prebuilt). Installato come root, eseguibile da thoth.
RUN npm install -g @earendil-works/pi-coding-agent@${PI_VERSION}
# 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
RUN ln -s /opt/pi-runtime/node_modules/.bin/pi /usr/local/bin/pi \
&& test "$(pi --version)" = "$PI_VERSION"
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 \
@@ -72,8 +90,9 @@ ENV PATH="/opt/venv/bin:/usr/local/bin:$PATH" \
COPY scripts/verify-line-endings.sh /usr/local/bin/verify-line-endings
COPY docker/core-entrypoint.sh docker/session-migrate.sh docker/ensure-pi-trust.mjs /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/session-migrate.sh
&& chmod +x /app/docker/core-entrypoint.sh /app/docker/session-migrate.sh /app/docker/smoke/core-smoke.sh
WORKDIR /app/backend
USER thoth
+5
View File
@@ -1,5 +1,6 @@
# syntax=docker/dockerfile:1.7
# thothii-frontend: build Vite (React) + nginx-unprivileged (porta 8080).
ARG IMAGE_VERSION=local
FROM node:22-bookworm AS build
WORKDIR /src
COPY frontend/package*.json ./
@@ -9,6 +10,10 @@ ENV VITE_BASE=/ VITE_BACKEND_URL=/api
RUN npm run build
FROM nginxinc/nginx-unprivileged:1.27-alpine AS runtime
ARG IMAGE_VERSION
LABEL org.opencontainers.image.title="thothii-frontend" \
org.opencontainers.image.version="${IMAGE_VERSION}" \
org.opencontainers.image.description="ThothII standalone frontend"
COPY --from=build /src/dist /usr/share/nginx/html
COPY docker/nginx.conf.template /etc/nginx/templates/default.conf.template
COPY --chmod=755 docker/frontend-entrypoint.sh /usr/local/bin/frontend-entrypoint
+3
View File
@@ -9,6 +9,9 @@
"version": "1.0.0",
"dependencies": {
"@earendil-works/pi-coding-agent": "0.80.3"
},
"engines": {
"node": ">=22.19.0"
}
},
"node_modules/@earendil-works/pi-coding-agent": {
+3
View File
@@ -3,6 +3,9 @@
"version": "1.0.0",
"private": true,
"description": "Locked Pi runtime dependency for the ThothII core image",
"engines": {
"node": ">=22.19.0"
},
"dependencies": {
"@earendil-works/pi-coding-agent": "0.80.3"
}
+6 -2
View File
@@ -1,7 +1,8 @@
#!/bin/sh
set -eu
test "$(id -u)" != "0"
test "$(id -u)" = "10001"
test -n "${PI_VERSION:-}"
node_version="$(node --version)"
python_version="$(python --version 2>&1)"
@@ -15,7 +16,10 @@ case "$python_version" in
esac
tht --help >/dev/null
pi --version >/dev/null
test "$(pi --version)" = "$PI_VERSION"
test ! -e /var/run/docker.sock
touch /data/.core-smoke-writable
rm /data/.core-smoke-writable
/app/docker/core-entrypoint.sh server &
server_pid=$!