c4a429d952
Punto 12. Le cinque librerie erano già state portate in casa (28ee44b): nessun
template carica più niente dalla rete, il worker di PDF.js è locale in tutti e
quattro i file che lo impostano, i font sono woff2 nel pacchetto. Verificato riga
per riga, e le impronte SHA-256 in VERSIONS.md corrispondono ancora.
Mancava però la seconda metà dell'intervento, e mancava dove conta. La
Content-Security-Policy a sola origine locale esisteva sul backend, cioè sulle
risposte API; le pagine HTML le serve il client Flask, che non mandava alcuna
policy. La regola stava scritta dove non poteva essere infranta e assente dove
poteva. Ora il client la manda su ogni risposta.
Serve meno a difendere e più a non far tornare indietro il punto: un tag verso un
CDN aggiunto fra sei mesi viene rifiutato dal browser alla scrivania, dove c'è la
rete e l'errore si legge in console, invece che in reparto dove la rete non c'è.
Tailwind era ancora agganciato a `tailwindcss@3` nel Dockerfile: stesso difetto
che il documento cita per le librerie del browser, un gradino più in basso. Fissato
a 3.4.19, che è la versione con cui l'immagine in esercizio è stata costruita.
I test non renderizzano niente: leggono i sorgenti, perché il difetto che devono
impedire si scrive in un template e non si vede finché non si stacca la rete.
Controllano anche le impronte — una libreria sostituita sul posto tiene lo stesso
nome e la stessa riga in tabella, e l'hash è l'unica parte che se ne accorge.
Annotato in VERSIONS.md che `html5-qrcode` è l'unica libreria dichiarata e mai
caricata: lo scanner da fotocamera non è incluso da nessuna pagina, il lettore che
l'operatore usa è un campo di testo. Va portata in casa prima di accenderlo.
README aggiornato a V3.0.0: novità della versione punto per punto, ruolo
Supervisor, librerie locali al posto dei CDN, stato dei test.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
49 lines
1.9 KiB
Docker
49 lines
1.9 KiB
Docker
FROM python:3.11-slim AS base
|
|
|
|
# uv from the official slim image (fast Python package manager).
|
|
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /usr/local/bin/
|
|
|
|
# Node.js 20 is needed at build time to compile TailwindCSS.
|
|
RUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates \
|
|
&& curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
|
|
&& apt-get install -y --no-install-recommends nodejs \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
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.
|
|
COPY src/frontend/flask_app/ ./flask_app/
|
|
|
|
# Build TailwindCSS (one-shot; no watcher in production image).
|
|
#
|
|
# 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.
|
|
WORKDIR /app/flask_app
|
|
RUN npm install tailwindcss@3.4.19 && \
|
|
npx tailwindcss -i static/css/input.css -o static/css/tailwind.css --minify
|
|
|
|
# Compile Flask-Babel translation catalogs.
|
|
RUN uv run --project /app pybabel compile -d translations
|
|
|
|
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()"]
|