d1833ba203
Punto 1: useradd -u 10001 app, chown /app (+ /app/uploads sul server), USER app in tutti e tre i Dockerfile. Stesso UID sul server e sul worker di visione, che condividono il volume uploads in sola lettura (punto 13). Punto 2: python:3.11.16-slim (server, client), python:3.13.15-slim (vision), ghcr.io/astral-sh/uv:0.10.9 (versione locale di `uv --version`). Dockerfile.frontend: TailwindCSS ora si compila in uno stage separato dall'immagine ufficiale node:20.20.2-bookworm-slim, non più con `curl | bash` su nodesource nell'immagine finale. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
56 lines
2.1 KiB
Docker
56 lines
2.1 KiB
Docker
# TailwindCSS built in its own stage, from the official Node image, instead
|
|
# of `curl | bash` against nodesource inside the final image (point 2, C2).
|
|
FROM node:20.20.2-bookworm-slim AS tailwind-build
|
|
|
|
WORKDIR /app/flask_app
|
|
COPY src/frontend/flask_app/ ./
|
|
|
|
# Versione esatta, non `tailwindcss@3`. Con il vincolo aperto ogni ricostruzione
|
|
# dell'immagine poteva prendere una minor diversa e produrre un CSS diverso senza
|
|
# che nessuno l'avesse validato: per un sistema che produce evidenze per audit
|
|
# ISO 9001 / IATF 16949 è lo stesso problema che il punto 12 risolve per le
|
|
# librerie del browser. Aggiornarla è una decisione, non un effetto collaterale.
|
|
RUN npm install tailwindcss@3.4.19 && \
|
|
npx tailwindcss -i static/css/input.css -o static/css/tailwind.css --minify
|
|
|
|
FROM python:3.11.16-slim AS base
|
|
|
|
# uv from the official slim image (fast Python package manager).
|
|
COPY --from=ghcr.io/astral-sh/uv:0.10.9 /uv /uvx /usr/local/bin/
|
|
|
|
# Non-root user the app runs as at runtime.
|
|
RUN useradd -u 10001 app
|
|
|
|
WORKDIR /app
|
|
|
|
# Resolve Python deps from the project lockfile (only the `client` extra).
|
|
COPY pyproject.toml uv.lock ./
|
|
COPY .python-version ./
|
|
RUN uv sync --frozen --no-dev --extra client
|
|
|
|
# Copy the Flask app sources, then overlay the TailwindCSS build produced in
|
|
# the node stage above — the final image never installs Node.
|
|
COPY src/frontend/flask_app/ ./flask_app/
|
|
COPY --from=tailwind-build /app/flask_app/static/css/tailwind.css ./flask_app/static/css/tailwind.css
|
|
|
|
# Compile Flask-Babel translation catalogs.
|
|
WORKDIR /app/flask_app
|
|
RUN uv run --project /app pybabel compile -d translations && \
|
|
chown -R app:app /app
|
|
|
|
USER app
|
|
|
|
EXPOSE 5000
|
|
|
|
# Gunicorn behind Nginx/Traefik. Worker count and proxy trust kept in sync
|
|
# with the per-tablet rate-limiting fix (see V2.0.0 perf commit).
|
|
CMD ["uv", "run", "--project", "/app", "gunicorn", \
|
|
"--workers", "5", \
|
|
"--threads", "4", \
|
|
"--worker-class", "gthread", \
|
|
"--timeout", "60", \
|
|
"--bind", "0.0.0.0:5000", \
|
|
"--access-logfile", "-", \
|
|
"--forwarded-allow-ips", "*", \
|
|
"app:create_app()"]
|