Files
semantica/Dockerfile
T
Mohd KaifandClaude Sonnet 5 b8011eb44a fix(docker): revert runtime base image to python:3.13-slim (#1509)
#1290 bumped the runtime stage to python:3.14-slim. gensim is a base
(non-extras-gated) dependency and publishes no cp314 wheel on PyPI, so
pip falls back to building it from source, which needs a C compiler
this slim image doesn't carry:

  error: [Errno 2] No such file or directory: 'gcc'

This has broken the Docker build (and Container Security Scan) on
every push to main since #1290 merged. Confirmed via
`pip index versions gensim` / the PyPI files listing that gensim 4.4.0
ships cp313 wheels but no cp314 ones; the earlier lockfile fix in
#1290 only validated that `uv pip compile` could *resolve* dependencies
for 3.14, which reads sdist metadata and doesn't need a compiler --
it doesn't validate that `pip install` can actually *build* them,
which is what fails here.

Reverts to the exact base image digest that was building successfully
before #1290 and regenerates explorer-extra-py313.txt against today's
PyPI state. Once gensim (and anything else pulled in transitively)
ships cp314 wheels, the 3.14 bump can be retried.

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-07 15:29:41 +05:30

86 lines
4.4 KiB
Docker

# syntax=docker/dockerfile:1
FROM node:26-alpine@sha256:2d984a15c9b54fd0aeb608b8e0d0d83529eb34d2966db27a1fb4f1edc3d298a3 AS frontend-builder
WORKDIR /app
COPY explorer/package*.json ./explorer/
WORKDIR /app/explorer
RUN npm ci
COPY explorer/ ./
RUN mkdir -p /app/semantica && npm run build
# CVE-2026-14456 (OpenSSL QUIC-server DoS, flagged against this base image's
# openssl/libssl3t64/openssl-provider-legacy): the Debian fix
# (3.5.7-1~deb13u2) is only in trixie-proposed-updates as of this writing,
# not yet promoted to trixie-security, so there's no package to pin here
# today. Deliberately NOT running `apt-get upgrade` to chase it - that
# breaks build reproducibility (terrascan AC_DOCKER_0052) and still
# wouldn't reach a proposed-updates-only package. Once Debian ships the fix
# and rebuilds this tag, the docker Dependabot ecosystem in
# .github/dependabot.yml opens a PR bumping the digest pin above. Also: this
# image only serves plain HTTP via uvicorn and never opens a QUIC listener,
# so the bug isn't reachable here regardless.
#
# Pinned to 3.13, NOT 3.14: #1290 bumped this to python:3.14-slim and broke
# the build outright (Container Security Scan, every run since) - gensim
# (a base, non-extras-gated dependency) ships no cp314 wheel on PyPI yet, so
# pip falls back to building it from source, which needs a C compiler this
# slim image doesn't carry ("error: [Errno 2] No such file or directory:
# 'gcc'"). Revisit the 3.14 bump once gensim (and anything else pulled in
# transitively) publishes cp314 wheels - check with
# `pip index versions gensim` / the project's PyPI files page, not just
# whether `uv pip compile` resolves (resolution only reads sdist metadata,
# it doesn't attempt the build that fails here).
FROM python:3.13-slim@sha256:7ce4b6dfe35e55397b7cda544f8a13f191b7ae28dc5aad71fe664dbc9bc2623f AS runtime
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
FALKORDB_HOST=falkordb \
FALKORDB_PORT=6379 \
ALLOWED_ORIGINS=http://localhost:8000,http://127.0.0.1:8000
WORKDIR /app
RUN groupadd --system semantica \
&& useradd --system --gid semantica --home-dir /app --shell /usr/sbin/nologin semantica
COPY pyproject.toml README.md LICENSE MANIFEST.in \
.github/requirements/explorer-extra-py313.txt .github/requirements/pep517-build.txt ./
COPY semantica/ ./semantica/
COPY integrations/ ./integrations/
COPY --from=frontend-builder /app/semantica/static ./semantica/static
# explorer-extra-py313.txt is `uv pip compile pyproject.toml --extra explorer
# --python-version 3.13 --constraint requirements-ci.txt --generate-hashes`
# (see ci.yml's explorer-extra-py311.txt for the CI counterpart, resolved
# for CI's python 3.11 instead - the two aren't interchangeable: audioread
# (via librosa) needs standard-aifc/standard-sunau only on python>=3.13,
# since aifc/sunau left stdlib there, so a 3.11-resolved lockfile is
# missing hashes pip needs on this image's actual 3.13 interpreter and
# --require-hashes fails outright rather than silently under-pinning).
# Every fetched package is hash-verified (Scorecard Pinned-Dependencies)
# and pinned to the same versions CI audited, e.g. msgpack==1.2.1 and
# setuptools==84.0.0 (which also replaces the base image's vulnerable
# 70.3.0, CVE-2025-47273 - nothing else in the tree pulls a newer copy).
# --no-deps on the local package itself: it's our own source tree, not a
# fetch, so there's nothing to hash-pin there - but `pip install .` still
# does a PEP 517 build, which by default creates an *isolated* build env
# and fetches [build-system] requires (setuptools, wheel) completely
# outside any hash checking. pep517-build.txt pins that exact
# build-system.requires; installing it first and passing
# --no-build-isolation makes pip reuse those hash-verified copies instead
# of fetching its own.
RUN pip install --no-cache-dir -r explorer-extra-py313.txt -r pep517-build.txt --require-hashes \
&& pip install --no-cache-dir --no-deps --no-build-isolation . \
&& rm -f explorer-extra-py313.txt pep517-build.txt \
&& chown -R semantica:semantica /app
USER semantica
EXPOSE 8000
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
CMD python -c "import json, urllib.request; data=json.load(urllib.request.urlopen('http://127.0.0.1:8000/api/health', timeout=3)); raise SystemExit(0 if data.get('status') == 'ok' else 1)"
CMD ["python", "-m", "uvicorn", "semantica.explorer.app:app", "--host", "0.0.0.0", "--port", "8000"]